名域 ts {
    常量 枚举 签名标志_ {
        无_ = 0,
        类型_ = 1 << 0,
        需要完整的参数列表_ = 1 << 1,
        忽略失踪大括号_ = 1 << 2,
        JSDoc = 1 << 3,
    }

    // tslint:disable variable-名称
    变量 节点构造器_: 新建 (种类: 语法_, 首位?: 数字, 尾位?: 数字) => 节点_;
    变量 令牌构造器_: 新建 (种类: 语法_, 首位?: 数字, 尾位?: 数字) => 节点_;
    变量 标识符构造器_: 新建 (种类: 语法_, 首位?: 数字, 尾位?: 数字) => 节点_;
    变量 源文件构造器_: 新建 (种类: 语法_, 首位?: 数字, 尾位?: 数字) => 节点_;
    // tslint:enable variable-名称

    导出 函数 创建节点(种类: 语法_, 首位?: 数字, 尾位?: 数字): 节点_ {
        如果 (种类 === 语法_.源文件_) {
            返回 新建 (源文件构造器_ || (源文件构造器_ = 对象分配器.获取源文件构造器()))(种类, 首位, 尾位);
        }
        否则 如果 (种类 === 语法_.标识符_) {
            返回 新建 (标识符构造器_ || (标识符构造器_ = 对象分配器.获取标识符构造器()))(种类, 首位, 尾位);
        }
        否则 如果 (!是节点种类(种类)) {
            返回 新建 (令牌构造器_ || (令牌构造器_ = 对象分配器.获取令牌构造器()))(种类, 首位, 尾位);
        }
        否则 {
            返回 新建 (节点构造器_ || (节点构造器_ = 对象分配器.获取节点构造器()))(种类, 首位, 尾位);
        }
    }

    函数 访问节点<T>(cbn: (n: 节点_) => T, n: 节点_ | 未定): T | 未定 {
        返回 n && cbn(n);
    }

    函数 访问节点组<T>(cbn: (n: 节点_) => T, cbns: ((n: 节点数组_<节点_>) => T | 未定) | 未定, ns: 节点数组_<节点_> | 未定): T | 未定 {
        如果 (ns) {
            如果 (cbns) {
                返回 cbns(ns);
            }
            循环 (常量 n 属于 ns) {
                常量 结果 = cbn(n);
                如果 (结果) {
                    返回 结果;
                }
            }
        }
    }

    导出 函数 遍历子节点<T>(n: 节点_, cbn: (n: 节点_) => T | 未定, cbns?: (ns: 节点数组_<节点_>) => T | 未定): T | 未定 {
        如果 (!n || n.种类 <= 语法_.尾令牌_) {
            返回;
        }
        假如 (n.种类) {
            若是 语法_.限定名_:
                返回 访问节点(cbn, (<限定名_>n).左侧) ||
                    访问节点(cbn, (<限定名_>n).右侧);
            若是 语法_.类型参数声明_:
                返回 访问节点(cbn, (<类型参数声明_>n).名称) ||
                    访问节点(cbn, (<类型参数声明_>n).约束) ||
                    访问节点(cbn, (<类型参数声明_>n).默认) ||
                    访问节点(cbn, (<类型参数声明_>n).表达式);
            若是 语法_.程序声明_:
                返回 访问节点组(cbn, cbns, (<程序声明_>n).语句组);
            若是 语法_.参数_:
                返回 访问节点(cbn, (<参数声明_>n).名称) ||
                    访问节点(cbn, (<参数声明_>n).类型);
            若是 语法_.展开元素_:
                返回 访问节点(cbn, (<展开元素_>n).表达式);
            若是 语法_.接受者声明_:
                返回 访问节点(cbn, (<接受者声明_>n).类型);
            若是 语法_.属性声明_:
                返回 访问节点(cbn, (<属性声明_>n).名称) ||
                    访问节点(cbn, (<属性声明_>n).类型);
            若是 语法_.变量声明_:
                返回 访问节点(cbn, (<变量声明_>n).名称) ||
                    访问节点(cbn, (<变量声明_>n).类型);
            若是 语法_.常量声明_:
                返回 访问节点(cbn, (<常量声明_>n).名称)
            若是 语法_.变量语句_:
                返回 访问节点组(cbn, cbns, (<变量语句_>n).声明组) ||
                    访问节点组(cbn, cbns, (<变量语句_>n).初始化组);
            若是 语法_.简洁变量语句_:
                返回 访问节点组(cbn, cbns, (<简洁变量语句_>n).声明组) ||
                    访问节点组(cbn, cbns, (<简洁变量语句_>n).初始化组);
            若是 语法_.常量列表元素_:
                返回 访问节点(cbn, (<常量列表元素_>n).名称) ||
                    访问节点(cbn, (<常量列表元素_>n).初始化);
            若是 语法_.常量语句_:
                返回 访问节点组(cbn, cbns, (<常量语句_>n).声明组) ||
                    访问节点组(cbn, cbns, (<常量语句_>n).初始化组);
            若是 语法_.常量列表语句_:
                返回 访问节点组(cbn, cbns, (<常量列表语句_>n).声明组);
            若是 语法_.枚举声明_:
                返回 访问节点(cbn,(<枚举声明_>n).名称)||
                     访问节点组(cbn,cbns, (<枚举声明_>n).成员);
            若是 语法_.枚举成员声明_:
                返回 访问节点(cbn, (<枚举成员声明_>n).名称)||
                    访问节点(cbn, (<枚举成员声明_>n).初始化);
            若是 语法_.函数类型_:
                返回 访问节点组(cbn, cbns, (<函数类型节点_>n).类型参数) ||
                    访问节点组(cbn, cbns, (<函数类型节点_>n).参数) ||
                    访问节点(cbn, (<函数类型节点_>n).类型);
            若是 语法_.方法声明_:
                返回 访问节点(cbn, (<方法声明_>n).接受者) ||
                    访问节点(cbn, (<方法声明_>n).名称) ||
                    访问节点组(cbn, cbns, (<方法声明_>n).类型参数) ||
                    访问节点组(cbn, cbns, (<方法声明_>n).参数) ||
                    访问节点(cbn, (<方法声明_>n).类型) ||
                    访问节点(cbn, (<方法声明_>n).主体);
            若是 语法_.函数签名_:
                返回 访问节点(cbn, (<函数签名_>n).名称) ||
                    访问节点组(cbn, cbns, (<函数签名_>n).类型参数) ||
                    访问节点组(cbn, cbns, (<函数签名_>n).参数) ||
                    访问节点(cbn, (<函数签名_>n).类型);
            若是 语法_.创建函数签名_:
                返回 访问节点(cbn, (<创建函数签名_>n).名称) ||
                    访问节点组(cbn, cbns, (<创建函数签名_>n).类型参数) ||
                    访问节点组(cbn, cbns, (<创建函数签名_>n).参数) ||
                    访问节点(cbn, (<创建函数签名_>n).类型);
            若是 语法_.方法签名_:
                返回 访问节点(cbn, (<方法签名_>n).名称) ||
                    访问节点组(cbn, cbns, (<方法签名_>n).类型参数) ||
                    访问节点组(cbn, cbns, (<方法签名_>n).参数) ||
                    访问节点(cbn, (<方法签名_>n).类型);
            若是 语法_.函数表达式_:
                返回 访问节点(cbn, (<函数表达式_>n).名称) ||
                    访问节点组(cbn, cbns, (<函数表达式_>n).类型参数) ||
                    访问节点组(cbn, cbns, (<函数表达式_>n).参数) ||
                    访问节点(cbn, (<函数表达式_>n).类型) ||
                    访问节点(cbn, (<函数表达式_>n).主体);
            若是 语法_.启动函数声明_:
                返回 访问节点(cbn, (<启动函数声明_>n).名称) ||
                    访问节点(cbn, (<启动函数声明_>n).主体);
            若是 语法_.初始函数声明_:
                返回 访问节点(cbn, (<初始函数声明_>n).名称) ||
                    访问节点(cbn, (<初始函数声明_>n).主体);
            若是 语法_.函数声明_:
                返回 访问节点(cbn, (<函数声明_>n).名称) ||
                    访问节点组(cbn, cbns, (<函数声明_>n).类型参数) ||
                    访问节点组(cbn, cbns, (<函数声明_>n).参数) ||
                    访问节点(cbn, (<函数声明_>n).类型) ||
                    访问节点(cbn, (<函数声明_>n).主体);
            若是 语法_.箭头函数_:
                返回 访问节点组(cbn, cbns, (<箭头函数_>n).类型参数) ||
                    访问节点组(cbn, cbns, (<箭头函数_>n).参数) ||
                    访问节点(cbn, (<箭头函数_>n).等右尖号) ||
                    访问节点(cbn, (<箭头函数_>n).类型) ||
                    访问节点(cbn, (<箭头函数_>n).主体);
            若是 语法_.类型引用_:
                返回 访问节点(cbn, (<类型引用节点_>n).类型名) ||
                    访问节点组(cbn, cbns, (<类型引用节点_>n).类型实参);
            若是 语法_.指针类型_:
                返回 访问节点(cbn, (<指针类型节点_>n).基础类型);
            若是 语法_.通信类型_:
                返回 访问节点(cbn, (<通信类型节点_>n).元素类型);
            若是 语法_.只读通信_:
                返回 访问节点(cbn, (<只读通信节点_>n).元素类型);
            若是 语法_.只写通信_:
                返回 访问节点(cbn, (<只写通信节点_>n).元素类型);
            若是 语法_.数组类型_:
                返回 访问节点(cbn, (<数组类型节点_>n).元素类型) ||
                    访问节点(cbn, (<数组类型节点_>n).长度);
            若是 语法_.列表类型_:
                返回 访问节点(cbn, (<列表类型节点_>n).元素类型);
            若是 语法_.词典类型_:
                返回 访问节点(cbn, (<词典类型节点_>n).键类型) ||
                    访问节点(cbn, (<词典类型节点_>n).值类型);
            若是 语法_.联合类型_:
            若是 语法_.交叉类型_:
                返回 访问节点组(cbn, cbns, (<联合类型节点_ | 交叉类型节点_>n).类型组);
            若是 语法_.括号类型_:
                返回 访问节点(cbn, (<括号类型节点_>n).类型);
            若是 语法_.数组字面量表达式_:
                返回 访问节点(cbn, (<数组字面量表达式_>n).元素类型) ||
                    访问节点组(cbn, cbns, (<数组字面量表达式_>n).元素);
            若是 语法_.列表字面量表达式_:
                返回 访问节点(cbn, (<列表字面量表达式_>n).元素类型) ||
                    访问节点组(cbn, cbns, (<列表字面量表达式_>n).元素);
            若是 语法_.数组或列表字面量表达式_:
                返回 访问节点组(cbn, cbns, (<数组或列表字面量表达式_>n).元素);
            若是 语法_.结构字面量表达式_:
                返回 访问节点(cbn, (<结构字面量表达式_>n).结构体类型名) ||
                    访问节点组(cbn, cbns, (<结构字面量表达式_>n).属性组);
            若是 语法_.结构字面量成员表达式_:
                返回 访问节点(cbn, (<结构字面量成员表达式_>n).名称) ||
                    访问节点(cbn, (<结构字面量成员表达式_>n).初始化);
            若是 语法_.属性访问表达式_:
                返回 访问节点(cbn, (<属性访问表达式_>n).表达式) ||
                    访问节点(cbn, (<属性访问表达式_>n).名称);
            若是 语法_.元素访问表达式_:
                返回 访问节点(cbn, (<元素访问表达式_>n).表达式) ||
                    访问节点(cbn, (<元素访问表达式_>n).参数表达式);
            若是 语法_.取址表达式_:
            若是 语法_.取值表达式_:
                返回 访问节点(cbn, (<取址表达式_ | 取值表达式_>n).算子);
            若是 语法_.调用表达式_:
                返回 访问节点(cbn, (<调用表达式_>n).表达式) ||
                    访问节点组(cbn, cbns, (<调用表达式_>n).类型实参)||
                    访问节点组(cbn, cbns, (<调用表达式_>n).实参组);
            若是 语法_.新建表达式_:
                返回 访问节点(cbn, (<新建表达式_>n).类型参数)||
                    访问节点组(cbn, cbns, (<调用表达式_>n).类型实参);
            若是 语法_.创建表达式_:
                返回 访问节点组(cbn, cbns, (<创建表达式_>n).类型实参) ||
                    访问节点(cbn, (<创建表达式_>n).实参1) ||
                    访问节点(cbn, (<创建表达式_>n).实参2);
            若是 语法_.执行语句_:
                返回 访问节点(cbn, (<执行语句_>n).表达式);
            若是 语法_.善后语句_:
                返回 访问节点(cbn, (<善后语句_>n).表达式);
            若是 语法_.删除语句_:
                返回 访问节点(cbn, (<删除语句_>n).表达式);
            若是 语法_.标记模板表达式_:
                返回 访问节点(cbn, (<标记模板表达式_>n).标签) ||
                    访问节点(cbn, (<标记模板表达式_>n).模板);
            若是 语法_.类型断言表达式_:
                返回 访问节点(cbn, (<类型断言表达式_>n).表达式) ||
                    访问节点(cbn, (<类型断言表达式_>n).类型);
            若是 语法_.括号表达式_:
                返回 访问节点(cbn, (<括号表达式_>n).表达式);
            若是 语法_.无值表达式_:
                返回 访问节点(cbn, (<无值表达式_>n).表达式);
            若是 语法_.前缀一元表达式_:
                返回 访问节点(cbn, (<前缀一元表达式_>n).算子);
            若是 语法_.后缀一元表达式_:
                返回 访问节点(cbn, (<后缀一元表达式_>n).算子);
            若是 语法_.二元表达式_:
                返回 访问节点(cbn, (<二元表达式_>n).左侧) ||
                    访问节点(cbn, (<二元表达式_>n).运算符令牌) ||
                    访问节点(cbn, (<二元表达式_>n).右侧);
            若是 语法_.类型查询表达式_:
                返回 访问节点(cbn, (<类型查询表达式_>n).表达式);
            若是 语法_.类型转换表达式_:
                返回 访问节点(cbn, (<类型转换表达式_>n).类型) ||
                    访问节点(cbn, (<类型转换表达式_>n).表达式);
            若是 语法_.条件表达式_:
                返回 访问节点(cbn, (<条件表达式_>n).条件) ||
                    访问节点(cbn, (<条件表达式_>n).问号) ||
                    访问节点(cbn, (<条件表达式_>n).当为真) ||
                    访问节点(cbn, (<条件表达式_>n).冒号) ||
                    访问节点(cbn, (<条件表达式_>n).当为假);
            若是 语法_.块_:
            若是 语法_.源文件_:
                返回 访问节点组(cbn, cbns, (<源文件_>n).语句组) ||
                    访问节点(cbn, (<源文件_>n).文件结尾令牌);
            若是 语法_.表达式语句_:
                返回 访问节点(cbn, (<表达式语句_>n).表达式);
            若是 语法_.如果语句_:
                返回 访问节点(cbn, (<如果语句_>n).表达式) ||
                    访问节点(cbn, (<如果语句_>n).然后语句) ||
                    访问节点(cbn, (<如果语句_>n).另如语句) ||
                    访问节点(cbn, (<如果语句_>n).否则语句);
            若是 语法_.另如语句_:
                返回 访问节点(cbn, (<另如语句_>n).表达式) ||
                    访问节点(cbn, (<另如语句_>n).然后语句) ||
                    访问节点(cbn, (<另如语句_>n).另如语句) ||
                    访问节点(cbn, (<另如语句_>n).否则语句);
            若是 语法_.循环语句_:
                返回 访问节点(cbn, (<循环语句_>n).初始化) ||
                    访问节点(cbn, (<循环语句_>n).条件) ||
                    访问节点组(cbn, cbns, (<循环语句_>n).增量器) ||
                    访问节点(cbn, (<循环语句_>n).迭代体);
            若是 语法_.循环属于语句_:
                返回 访问节点组(cbn, cbns, (<循环属于语句_>n).声明组) ||
                    访问节点(cbn, (<循环属于语句_>n).表达式) ||
                    访问节点(cbn, (<循环属于语句_>n).迭代体);
            若是 语法_.继续语句_:
            若是 语法_.跳出语句_:
            若是 语法_.贯穿语句_:
                返回 访问节点(cbn, (<跳出或继续语句_>n).标签);
            若是 语法_.返回语句_:
                返回 访问节点组(cbn, cbns, (<返回语句_>n).表达式);
            若是 语法_.选择语句_:
                返回 访问节点(cbn, (<选择语句_>n).表达式) ||
                    访问节点(cbn, (<选择语句_>n).若是块);
            若是 语法_.假如语句_:
                返回 访问节点(cbn, (<假如语句_>n).表达式) ||
                    访问节点(cbn, (<假如语句_>n).若是块);
            若是 语法_.若是块_:
                返回 访问节点组(cbn, cbns, (<若是块_>n).子句组);
            若是 语法_.若是子句_:
                返回 访问节点(cbn, (<若是子句_>n).表达式) ||
                    访问节点组(cbn, cbns, (<若是子句_>n).语句组);
            若是 语法_.默认子句_:
                返回 访问节点组(cbn, cbns, (<默认子句_>n).语句组);
            若是 语法_.标签语句_:
                返回 访问节点(cbn, (<标签语句_>n).标签) ||
                    访问节点(cbn, (<标签语句_>n).语句);
            若是 语法_.结构声明_:
                返回 访问节点(cbn, (<结构声明_>n).名称) ||
                    访问节点组(cbn, cbns, (<结构声明_>n).类型参数)||
                    访问节点组(cbn, cbns, (<结构声明_>n).成员);
            若是 语法_.返回值声明属性组_:
            若是 语法_.结构声明属性组_:
                返回 访问节点组(cbn, cbns, (<结构声明属性组_ | 返回值声明属性组_>n).声明组);
            若是 语法_.接口声明_:
                返回 访问节点(cbn, (<接口声明_>n).名称) || 
                    访问节点组(cbn, cbns, (<接口声明_>n).类型参数)||
                    访问节点组(cbn, cbns, (<接口声明_>n).成员);
            若是 语法_.类型别名声明_:
                返回 访问节点(cbn, (<类型别名声明_>n).名称) ||
                    访问节点组(cbn, cbns, (<类型别名声明_>n).类型参数) ||
                    访问节点(cbn, (<类型别名声明_>n).类型);
            若是 语法_.类型声明_:
                返回 访问节点(cbn, (<类型声明_>n).名称) ||
                    访问节点组(cbn, cbns, (<类型声明_>n).类型参数) ||
                    访问节点(cbn, (<类型声明_>n).类型);
            若是 语法_.导入成员_:
                返回 访问节点(cbn, (<导入成员_>n).名称) ||
                    访问节点(cbn, (<导入成员_>n).别名) ||
                    访问节点(cbn, (<导入成员_>n).模块名);
            若是 语法_.导入声明_:
                返回 访问节点组(cbn, cbns, (<导入声明_>n).导入组);
            若是 语法_.导入从成员_:
                返回 访问节点(cbn, (<导入从成员_>n).名称) ||
                    访问节点(cbn, (<导入从成员_>n).别名);
            若是 语法_.导入从声明_:
                返回 访问节点组(cbn, cbns, (<导入从声明_>n).导入组) ||
                    访问节点(cbn, (<导入从声明_>n).模块名);
            若是 语法_.模板表达式_:
                返回 访问节点(cbn, (<模板表达式_>n).头部) ||
                    访问节点组(cbn, cbns, (<模板表达式_>n).模板跨度组);
            若是 语法_.模板跨度_:
                返回 访问节点(cbn, (<模板跨度_>n).表达式) ||
                    访问节点(cbn, (<模板跨度_>n).字面量);
            若是 语法_.部分输出表达式_:
                返回 访问节点(cbn, (<部分输出语句_>n).表达式);
        }
    }

    导出 函数 创建源文件(文件名: 文字, 源文本: 文字, 选项: 编译选项_, 设置父节点 = 为假, 脚本种类?: 脚本种类_): 源文件_ {
        性能.标记('开始解析');
        常量 结果 = 解析_.解析源文件(文件名, 源文本, 未定!, /*语法光标*/ 未定!, 选项, 设置父节点, 脚本种类);
        性能.标记('完成解析');
        性能.度量('解析', '开始解析', '完成解析');
        返回 结果;
    }

    导出 函数 解析独立实体名称(文本: 文字): 实体名称_ | 未定 {
        返回 解析_.解析独立实体名称(文本);
    }

    导出 函数 更新源文件(源文件: 源文件_, 新文本: 文字, 文本改变范围: 文本改变范围_, 选项: 编译选项_, 侵略性检查?: 真假): 源文件_ {
        常量 新源文件 = 增量解析器_.更新源文件(源文件, 新文本, 文本改变范围, 选项, 侵略性检查!);
        新源文件.标志 |= (源文件.标志 & 节点标志_.可能包含动态导入_);
        返回 新源文件;
    }

    /* @internal */
    导出 函数 解析独立JSDoc注释(内容: 文字, 开始?: 数字, length?: 数字) {
        常量 结果 = 解析_.JSDoc解析_.解析独立JSDoc注释(内容, 开始, length);
        如果 (结果 && 结果.jsDoc) {
            解析_.修复父引用(结果.jsDoc);
        }
        返回 结果;
    }

    名域 解析_ {
        常量 扫描器 = 创建扫描器(/*跳过杂项*/ 为真);
        变量 节点构造器_: 新建 (种类: 语法_, 首位: 数字, 尾位: 数字) => 节点_;
        变量 令牌构造器_: 新建 (种类: 语法_, 首位: 数字, 尾位: 数字) => 节点_;
        变量 标识符构造器_: 新建 (种类: 语法_, 首位: 数字, 尾位: 数字) => 节点_;
        变量 源文件构造器_: 新建 (种类: 语法_, 首位: 数字, 尾位: 数字) => 节点_;
        变量 源文件: 源文件_;
        变量 解析诊断信息: 诊断_[];
        变量 语法光标: 增量解析器_.语法光标_ | 未定;

        变量 当前令牌: 语法_;
        变量 源文本: 文字;
        变量 节点数量: 数字;
        变量 标识符组: 词典_<文字>;
        变量 标识符数量: 数字;

        变量 解析语义: 解析语义_;

        变量 节点语义标志: 节点标志_;

        变量 解析错误下个节点完成之前 = 为假;
        变量 当前选项: 编译选项_;
        变量 不跳过预处理尾部 = 为假;
        变量 定义的环境变量: 文字[];

        导出 函数 解析源文件(文件名: 文字, 源文本: 文字, 脚本目标: 脚本目标_, 语法光标: 增量解析器_.语法光标_ | 未定, 选项: 编译选项_, 设置父节点 = 为假, 脚本种类?: 脚本种类_): 源文件_ {
            脚本种类 = 确保脚本种类(文件名, 脚本种类);
            当前选项 = 选项;

            初始化状态(源文本, 语法光标, 脚本种类);

            常量 结果 = 解析源文件平台(文件名, 脚本目标, 设置父节点, 脚本种类);

            清除状态();

            返回 结果;
        }

        导出 函数 解析独立实体名称(内容: 文字): 实体名称_ | 未定 {
            初始化状态(内容, /*语法光标*/ 未定, 脚本种类_.K);
            下个令牌();
            常量 实体名称 = 解析实体名称(/*允许保留字*/ 为真);
            常量 是无效的 = 令牌() === 语法_.文件结尾令牌_ && !解析诊断信息.长度;
            清除状态();
            返回 是无效的 ? 实体名称 : 未定;
        }

        函数 获取语言版本(脚本种类: 脚本种类_) {
            返回 脚本种类 === 脚本种类_.K || 脚本种类 === 脚本种类_.DK || 脚本种类 === 脚本种类_.TestK ? 语言版本_.K : 语言版本_.标准_;
        }

        函数 初始化状态(_源码文本: 文字, _语法光标: 增量解析器_.语法光标_ | 未定, 脚本种类: 脚本种类_) {
            节点构造器_ = 对象分配器.获取节点构造器();
            令牌构造器_ = 对象分配器.获取令牌构造器();
            标识符构造器_ = 对象分配器.获取标识符构造器();
            源文件构造器_ = 对象分配器.获取源文件构造器();
            变量 架构文本 = `__${当前选项.架构 || 'amd64'}__`;
            变量 系统文本 = `__${当前选项.系统 || 'win'}__`;
            定义的环境变量! = 当前选项.定义!;
            附加如果唯一(定义的环境变量, 架构文本);
            附加如果唯一(定义的环境变量, 系统文本);
            源文本 = _源码文本;
            语法光标 = _语法光标!;
            解析诊断信息 = [];
            解析语义 = 0;
            标识符组 = 创建词典<文字>();
            标识符数量 = 0;
            节点数量 = 0;

            假如 (脚本种类) {
                若是 脚本种类_.K:
                    节点语义标志 = 节点标志_.Klang文件_;
                    跳出;
                默认:
                    节点语义标志 = 节点标志_.无_;
                    跳出;
            }
            解析错误下个节点完成之前 = 为假;

            扫描器.设置文本(源文本);
            扫描器.设置正在错误(扫描错误);
        }

        函数 清除状态() {
            扫描器.设置文本('');
            扫描器.设置正在错误(未定!);
            解析诊断信息 = 未定!;
            源文件 = 未定!;
            标识符组 = 未定!;
            语法光标 = 未定!;
            源文本 = 未定!;
            定义的环境变量 = 未定!;
            不跳过预处理尾部 = 未定!;
        }

        函数 解析源文件平台(文件名: 文字, 脚本目标: 脚本目标_, 设置父节点: 真假, 脚本种类: 脚本种类_): 源文件_ {
            常量 是声明文件 = 是声明文件名称(文件名);
            如果 (是声明文件) {
                节点语义标志 |= 节点标志_.环境_;
            }

            源文件 = 创建源文件(文件名, 脚本目标, 脚本种类, 是声明文件);
            源文件.标志 = 节点语义标志;

            下个令牌();
            源文件.语句组 = 解析列表(解析语义_.顶级源码语句_, 解析源码语句)

            调试_.断言(令牌() === 语法_.文件结尾令牌_);
            源文件.文件结尾令牌 = 添加JSDoc注释(解析令牌节点());

            源文件.节点数量 = 节点数量;
            源文件.标识符数量 = 标识符数量;
            源文件.标识符组 = 标识符组;
            源文件.解析诊断信息 = 解析诊断信息;

            如果 (设置父节点) {
                修复父引用(源文件);
            }
            返回 源文件;
        }

        函数 添加JSDoc注释<T 扩展 有JSDoc_>(n: T): T {
            常量 注释组 = 获取JSDoc注释范围(n, 源文件.文本);
            如果 (注释组) {
                循环 (常量 注释 属于 注释组) {
                    n.jsDoc = 追加(n.jsDoc, JSDoc解析_.解析JSDoc注释(n, 注释.首位, 注释.尾位 - 注释.首位));
                }
            }
            返回 n;
        }

        导出 函数 修复父引用(根节点: 节点_) {
            变量 父节点: 节点_ = 根节点;
            遍历子节点(根节点, 访问节点);
            返回;
            函数 访问节点(nc: 节点_): 无值 {
                如果 (nc.父节点 !== 父节点) {
                    nc.父节点 = 父节点;

                    常量 储存父节点 = 父节点;
                    父节点 = nc;
                    遍历子节点(nc, 访问节点);
                    如果 (具有JSDoc节点组(nc)) {
                        循环 (常量 jsDoc 属于 nc.jsDoc!) {
                            jsDoc.父节点 = nc;
                            父节点 = jsDoc;
                            遍历子节点(jsDoc, 访问节点);
                        }
                    }
                    父节点 = 储存父节点;
                }
            }
        }

        函数 创建源文件(文件名: 文字, 脚本目标: 脚本目标_, 脚本种类: 脚本种类_, 是声明文件: 真假): 源文件_ {
            常量 源文件 = <源文件_>新建 源文件构造器_(语法_.源文件_, /*首位*/ 0, /* 尾位 */ 源文本.长度);
            节点数量++;
            源文件.文本 = 源文本;
            源文件.绑定诊断信息组 = [];
            源文件.脚本目标 = 脚本目标;
            源文件.文件名 = 正规化路径(文件名);
            源文件.语言版本 = 获取语言版本(脚本种类);
            源文件.是声明文件 = 是声明文件;
            源文件.脚本种类 = 脚本种类;
            返回 源文件;
        }

        函数 解析错误在当前令牌(消息: 诊断信息_, 实参0?: 任意): 无值 {
            常量 开始 = 扫描器.获取令牌首位();
            常量 长度 = 扫描器.获取文本首位() - 开始;

            解析错误在位置(开始, 长度, 消息, 实参0);
        }

        函数 解析错误在位置(开始: 数字, 长度: 数字, 消息: 诊断信息_, 实参0?: 任意): 无值 {
            常量 最后错误 = 最后或未定义(解析诊断信息);
            如果 (!最后错误 || 开始 !== 最后错误.开始) {
                解析诊断信息.压入(创建文件诊断信息(源文件, 开始, 长度, 消息, 实参0));
            }
            解析错误下个节点完成之前 = 为真;
        }

        函数 扫描错误(消息: 诊断信息_, 长度?: 数字) {
            常量 首位 = 扫描器.获取文本首位();
            解析错误在位置(首位, 长度 || 0, 消息);
        }

        函数 获取节点首位(): 数字 {
            返回 扫描器.获取开始首位();
        }

        函数 令牌(): 语法_ {
            返回 当前令牌;
        }

        函数 下个令牌(): 语法_ {
            返回 当前令牌 = 扫描器.扫描();
        }

        函数 预扫描右尖号令牌(): 语法_ {
            返回 当前令牌 = 扫描器.预扫描右尖号令牌();
        }

        函数 预扫描斜杠号令牌(): 语法_ {
            返回 当前令牌 = 扫描器.预扫描斜杠号令牌();
        }

        函数 预扫描模板令牌(): 语法_ {
            返回 当前令牌 = 扫描器.预扫描模板令牌();
        }

        函数 推测助手<T>(cb: () => T, 是向前看: 真假): T {
            常量 储存令牌 = 当前令牌;
            常量 储存解析诊断信息长度 = 解析诊断信息.长度;
            常量 储存解析错误下个节点完成之前 = 解析错误下个节点完成之前;
            常量 储存节点语义标志 = 节点语义标志;

            常量 结果 = 是向前看
                ? 扫描器.前瞻(cb)
                : 扫描器.尝试扫描(cb);

            调试_.断言(储存节点语义标志 === 节点语义标志);
            如果 (!结果 || 是向前看) {
                当前令牌 = 储存令牌;
                解析诊断信息.长度 = 储存解析诊断信息长度;
                解析错误下个节点完成之前 = 储存解析错误下个节点完成之前;
            }

            返回 结果;
        }

        函数 前瞻<T>(cb: () => T): T {
            返回 推测助手(cb, /*是向前看*/ 为真);
        }

        函数 尝试解析<T>(cb: () => T): T {
            返回 推测助手(cb, /*是向前看*/ 为假);
        }

        函数 是标识符(): 真假 {
            返回 令牌() === 语法_.标识符_ || 令牌() > 语法_.假_;
        }

        函数 解析预期(种类: 语法_, 诊断信息?: 诊断信息_, 向前 = 为真): 真假 {
            如果 (令牌() === 种类) {
                如果 (向前) {
                    下个令牌();
                }
                返回 为真;
            }
            如果 (诊断信息) {
                解析错误在当前令牌(诊断信息);
            }
            否则 {
                解析错误在当前令牌(诊断信息_.应为_0, 令牌转为文字(种类));
            }
            返回 为假;
        }

        函数 解析可选(t: 语法_): 真假 {
            如果 (令牌() === t) {
                下个令牌();
                返回 为真;
            }
            返回 为假;
        }

        函数 解析可选令牌<T种类_ 扩展 语法_>(t: T种类_): 令牌_<T种类_>;
        函数 解析可选令牌(t: 语法_): 节点_ | 未定 {
            如果 (令牌() === t) {
                返回 解析令牌节点();
            }
            返回 未定;
        }

        函数 解析预期令牌<T种类_ 扩展 语法_>(t: T种类_, 诊断信息?: 诊断信息_, 实参0?: 任意): 令牌_<T种类_>;
        函数 解析预期令牌(t: 语法_, 诊断信息?: 诊断信息_, 实参0?: 任意): 节点_ {
            返回 解析可选令牌(t) || 创建失踪节点(t, /*报告当前位置*/ 为假, 诊断信息 || 诊断信息_.应为_0, 实参0 || 令牌转为文字(t));
        }

        函数 解析令牌节点<T 扩展 节点_>(): T {
            常量 n = <T>创建节点(令牌());
            下个令牌();
            返回 完成节点(n);
        }

        函数 可以解析分号() {
            如果 (令牌() === 语法_.分号_) {
                返回 为真;
            }
            返回 令牌() === 语法_.右大括号_ || 令牌() === 语法_.文件结尾令牌_ || 扫描器.具有前导换行符();
        }

        函数 解析分号(): 真假 {
            如果 (可以解析分号()) {
                如果 (令牌() === 语法_.分号_) {
                    下个令牌();
                }

                返回 为真;
            }
            否则 {
                返回 解析预期(语法_.分号_);
            }
        }

        函数 创建节点(种类: 语法_, 首位?: 数字): 节点_ {
            节点数量++;
            常量 p = 首位! >= 0 ? 首位! : 扫描器.获取开始首位();
            返回 是节点种类(种类) || 种类 === 语法_.未知_ ? 新建 节点构造器_(种类, p, p) :
                种类 === 语法_.标识符_ ? 新建 标识符构造器_(种类, p, p) :
                    新建 令牌构造器_(种类, p, p);
        }

        函数 创建节点包括JSDoc(种类: 语法_): 节点_ {
            常量 n = 创建节点(种类);
            如果 (扫描器.获取令牌标志() & 令牌标志_.前导JSDoc注释_) {
                添加JSDoc注释(<有JSDoc_>n);
            }
            返回 n;
        }

        函数 创建节点数组<T 扩展 节点_>(元素组: T[], 首位: 数字, 尾位?: 数字): 节点数组_<T> {
            常量 长度 = 元素组.长度;
            常量 数组 = <多维节点数组_<T>>(长度 >= 1 && 长度 <= 4 ? 元素组.分切() : 元素组);
            数组.首位 = 首位;
            数组.尾位 = 尾位 === 未定 ? 扫描器.获取开始首位() : 尾位;
            返回 数组;
        }

        函数 完成节点<T 扩展 节点_>(n: T, 尾位?: 数字): T {
            n.尾位 = 尾位 === 未定 ? 扫描器.获取开始首位() : 尾位;

            如果 (节点语义标志) {
                n.标志 |= 节点语义标志;
            }
            如果 (解析错误下个节点完成之前) {
                解析错误下个节点完成之前 = 为假;
                n.标志 |= 节点标志_.这个节点有错误_;
            }

            返回 n;
        }

        函数 创建失踪节点<T 扩展 节点_>(种类: T['种类'], 报告当前位置: 真假, 诊断信息: 诊断信息_, 实参0?: 任意): T {
            如果 (报告当前位置) {
                解析错误在位置(扫描器.获取开始首位(), 0, 诊断信息, 实参0);
            }
            否则 {
                解析错误在当前令牌(诊断信息, 实参0);
            }
            常量 结果 = 创建节点(种类);
            如果 (种类 === 语法_.标识符_) {
                (结果 转为 标识符_).文本 = '' 转为 文字;
            }
            否则 如果 (是字面量种类(种类) || 是模板字面量种类(种类)) {
                (结果 转为 字面量族节点_).文本 = '';
            }
            返回 完成节点(结果) 转为 T;
        }

        函数 初始化标识符(文本: 文字): 文字 {
            变量 标识符 = 标识符组.获取(文本);
            如果 (标识符 === 未定) {
                标识符组.设置(文本, 标识符 = 文本);
            }
            返回 标识符;
        }

        函数 创建标识符(是标识符: 真假, 诊断信息?: 诊断信息_): 标识符_ {
            标识符数量++;
            如果 (是标识符) {
                常量 n = <标识符_>创建节点(语法_.标识符_);
                如果 (令牌() !== 语法_.标识符_) {
                    n.原始关键字种类 = 令牌();
                }
                n.文本 = 初始化标识符(扫描器.获取令牌值());
                n.修饰符标志缓存 = 扫描器.获取令牌标志() & 令牌标志_.修饰符标志_
                下个令牌();
                返回 完成节点(n);
            }
            常量 报告当前位置 = 令牌() === 语法_.文件结尾令牌_;

            返回 创建失踪节点<标识符_>(语法_.标识符_, 报告当前位置, 诊断信息 || 诊断信息_.应为标识符);
        }

        函数 解析标识符(诊断信息?: 诊断信息_): 标识符_ {
            返回 创建标识符(是标识符(), 诊断信息);
        }

        函数 解析标识符名称(诊断信息?: 诊断信息_): 标识符_ {
            返回 创建标识符(令牌是标识符或关键字(令牌()), 诊断信息);
        }

        常量 枚举 解析语义_ {
            顶级源码语句_,
            源码元素_,
            跳出语句_,
            假如子句_,
            假如若是语句_,
            实参表达式_,
            数组字面量成员_,
            参数声明_,
            初始化组_,
            循环体内初始化_,
            解析导入从语句_,
            解析导入语句_,
            解析单行导入语句_,
            结构声明属性组_,
            结构成员声明_,
            循环增量语句块_,
            类型声明列表_,
            类型列表声明初始化_,
            返回值声明列表_,
            接口成员_,
            变量声明_,
            常量列表语句_,
            循环属于声明_,
            返回语句列表_,
            结构字面量成员_,
            词典字面量表达式_,
            数组列表成员_,
            导入语句_,
            类型参数_,
            类型实参_,
            枚举声明_,
            计数_
        }

        函数 解析语义错误(语义: 解析语义_): 诊断信息_ {
            假如 (语义) {
                若是 解析语义_.顶级源码语句_:
                若是 解析语义_.源码元素_: 返回 诊断信息_.除了导入语句及程序声明语句外不能为其他类型语句;
                若是 解析语义_.跳出语句_: 返回 诊断信息_.应有声明或语句;
                若是 解析语义_.假如子句_: 返回 诊断信息_.应有_若是_或_默认_语句
                若是 解析语义_.假如若是语句_: 返回 诊断信息_.应有语句;
                若是 解析语义_.实参表达式_: 返回 诊断信息_.应有参数表达式;
                若是 解析语义_.数组字面量成员_: 返回 诊断信息_.应有表达式或逗号;
                若是 解析语义_.参数声明_: 返回 诊断信息_.应有参数声明;
                若是 解析语义_.初始化组_: 返回 诊断信息_.应有表达式或逗号;
                若是 解析语义_.循环体内初始化_: 返回 诊断信息_.应有表达式或逗号;
                若是 解析语义_.解析导入从语句_: 返回 诊断信息_.应有语句;
                若是 解析语义_.解析导入语句_: 返回 诊断信息_.应有语句;
                若是 解析语义_.解析单行导入语句_: 返回 诊断信息_.应有表达式或逗号;
                若是 解析语义_.结构声明属性组_: 返回 诊断信息_.应有语句;
                若是 解析语义_.结构成员声明_: 返回 诊断信息_.应有语句;
                若是 解析语义_.循环增量语句块_: 返回 诊断信息_.应有语句;
                若是 解析语义_.类型声明列表_: 返回 诊断信息_.应有语句;
                若是 解析语义_.类型列表声明初始化_: 返回 诊断信息_.应有语句;
                若是 解析语义_.返回值声明列表_: 返回 诊断信息_.应有语句;
                若是 解析语义_.接口成员_: 返回 诊断信息_.应有语句;
                若是 解析语义_.变量声明_: 返回 诊断信息_.应有语句;
                若是 解析语义_.常量列表语句_: 返回 诊断信息_.应有声明或语句;
                若是 解析语义_.枚举声明_: 返回 诊断信息_.应为枚举声明;
                若是 解析语义_.循环属于声明_: 返回 诊断信息_.应有语句;
                若是 解析语义_.返回语句列表_: 返回 诊断信息_.应有表达式或逗号;
                若是 解析语义_.结构字面量成员_: 返回 诊断信息_.应有结构字面量表达式;
                若是 解析语义_.词典字面量表达式_: 返回 诊断信息_.应有词典字面量表达式
                若是 解析语义_.类型参数_: 返回 诊断信息_.Type_parameter_declaration_expected;
                若是 解析语义_.类型实参_: 返回 诊断信息_.Type_argument_expected;
                若是 解析语义_.数组列表成员_:
                默认: 返回 未定!;
            }
        }

        函数 是列表元素(语义: 解析语义_, 在错误恢复: 真假): 真假 {
            常量 n = 当前节点(语义);
            如果 (n) {
                返回 为真;
            }
            假如 (语义) {
                若是 解析语义_.参数声明_:
                    返回 是参数开始();

                若是 解析语义_.变量声明_:
                若是 解析语义_.类型声明列表_:
                若是 解析语义_.常量列表语句_:
                若是 解析语义_.枚举声明_:
                若是 解析语义_.循环属于声明_:
                    返回 是标识符();

                若是 解析语义_.接口成员_:
                若是 解析语义_.结构成员声明_:
                若是 解析语义_.结构声明属性组_:
                若是 解析语义_.返回值声明列表_:
                若是 解析语义_.类型列表声明初始化_:
                    返回 可能是类型名称节点();

                若是 解析语义_.初始化组_:
                若是 解析语义_.返回语句列表_:
                若是 解析语义_.结构字面量成员_:
                若是 解析语义_.循环体内初始化_:
                若是 解析语义_.循环增量语句块_:
                若是 解析语义_.词典字面量表达式_:
                    返回 是表达式开始();

                若是 解析语义_.假如子句_:
                    返回 令牌() === 语法_.若是_ || 令牌() === 语法_.默认_;

                若是 解析语义_.解析导入语句_:
                若是 解析语义_.解析导入从语句_:
                    返回 是标识符() || 令牌() === 语法_.文本字面量_

                若是 解析语义_.跳出语句_:
                若是 解析语义_.假如若是语句_:
                    返回 !(令牌() === 语法_.分号_ && 在错误恢复) && 是语句开始();
                若是 解析语义_.导入语句_:
                若是 解析语义_.源码元素_:
                    返回 !(令牌() === 语法_.分号_ && 在错误恢复) && 是顶级语句开始();
                若是 解析语义_.顶级源码语句_:
                    返回 !(令牌() === 语法_.分号_ && 在错误恢复) && (令牌() === 语法_.导入_ || 令牌() === 语法_.程序_ || 令牌() === 语法_.预_定义_ || 令牌() === 语法_.预_完成定义_ || 是顶级语句开始());

                若是 解析语义_.数组字面量成员_:
                    如果 (令牌() === 语法_.逗号_) {
                        返回 为真;
                    } // 贯穿
                若是 解析语义_.数组列表成员_:
                若是 解析语义_.实参表达式_:
                    返回 令牌() === 语法_.三点号_ || 令牌() === 语法_.左大括号_ || 是表达式开始();
                若是 解析语义_.类型参数_:
                    返回 是标识符()
                若是 解析语义_.类型实参_:
                    返回 令牌() === 语法_.逗号_ || 是类型开始()

                若是 解析语义_.解析单行导入语句_:
                    返回 令牌() === 语法_.标识符_ || 令牌() === 语法_.文本字面量_ || 令牌() === 语法_.数字字面量_;
            }
            返回 调试_.失败('不是有效的"列表元素"分类.');
        }

        函数 是列表终止(种类: 解析语义_): 真假 {
            如果 (令牌() === 语法_.文件结尾令牌_) {
                返回 为真;
            }
            假如 (种类) {
                若是 解析语义_.顶级源码语句_:
                    返回 为假 //令牌() !== 语法_.导入_ && 令牌() !== 语法_.程序_ && 令牌() !== 语法_.预_定义_ && 令牌() !== 语法_.预_完成定义_ || !是顶级语句开始();
                若是 解析语义_.导入语句_:
                    返回 令牌() !== 语法_.导入_;
                若是 解析语义_.跳出语句_:
                若是 解析语义_.假如子句_:
                若是 解析语义_.接口成员_:
                若是 解析语义_.解析导入语句_:
                若是 解析语义_.常量列表语句_:
                若是 解析语义_.枚举声明_:
                若是 解析语义_.数组列表成员_:
                若是 解析语义_.解析导入从语句_:
                若是 解析语义_.结构声明属性组_:
                若是 解析语义_.结构字面量成员_:
                若是 解析语义_.数组字面量成员_:
                若是 解析语义_.词典字面量表达式_:
                    返回 令牌() === 语法_.右大括号_;

                若是 解析语义_.初始化组_:
                若是 解析语义_.结构成员声明_:
                若是 解析语义_.返回语句列表_:
                    返回 可以解析分号()

                若是 解析语义_.参数声明_:
                若是 解析语义_.循环增量语句块_:
                    返回 令牌() === 语法_.右括号_

                若是 解析语义_.返回值声明列表_:
                    返回 是返回值终结者()

                若是 解析语义_.类型列表声明初始化_:
                    返回 是顶级语句开始();

                若是 解析语义_.循环属于声明_:
                    返回 令牌() === 语法_.属于_

                若是 解析语义_.循环体内初始化_:
                    返回 令牌() === 语法_.右括号_ || 可以解析分号()

                若是 解析语义_.实参表达式_:
                    返回 令牌() === 语法_.右括号_ || 令牌() === 语法_.分号_;

                若是 解析语义_.类型声明列表_:
                    返回 令牌() === 语法_.等号_ || 令牌() === 语法_.冒等号_;

                若是 解析语义_.解析单行导入语句_:
                    返回 令牌() === 语法_.分号_ || 前瞻(下个非杂项令牌前有换行符号);

                若是 解析语义_.变量声明_:
                    返回 令牌() === 语法_.冒等号_ || 令牌() === 语法_.等号_ || 可以解析分号();

                若是 解析语义_.假如若是语句_:
                    返回 令牌() === 语法_.右大括号_ || 令牌() === 语法_.若是_ || 令牌() === 语法_.默认_;
                若是 解析语义_.类型实参_:
                    返回 令牌() !== 语法_.逗号_
                若是 解析语义_.类型参数_:
                    返回 令牌() === 语法_.右尖号_ || 令牌() === 语法_.左括号_ || 令牌() === 语法_.左方括号_

                默认:
                    返回 为假;
            }
        }

        函数 是返回值终结者() {
            返回 令牌() === 语法_.右括号_ || 令牌() === 语法_.左大括号_ || 令牌() === 语法_.右大括号_ || 令牌() === 语法_.分号_ || 令牌() === 语法_.文件结尾令牌_ || 扫描器.具有前导换行符()
        }

        函数 下个非杂项令牌前有换行符号() {
            下个令牌()
            返回 扫描器.具有前导换行符();
        }

        函数 是在某些解析语义中(): 真假 {
            循环 (变量 种类 = 0; 种类 < 解析语义_.计数_; 种类++) {
                如果 (解析语义 & (1 << 种类)) {
                    如果 (是列表元素(种类, /*在错误恢复*/ 为真) || 是列表终止(种类)) {
                        返回 为真;
                    }
                }
            }
            返回 为假;
        }

        函数 解析列表<T 扩展 节点_>(种类: 解析语义_, 解析元素: () => T): 节点数组_<T> {
            常量 储存解析语义 = 解析语义;
            解析语义 |= 1 << 种类;
            常量 列表 = [];
            常量 列表首位 = 获取节点首位();

            判断 (!是列表终止(种类)) {
                如果 (是列表元素(种类, /*在错误恢复*/ 为假)) {
                    常量 元素 = 解析列表元素(种类, 解析元素);
                    列表.压入(元素);

                    继续;
                }

                如果 (终止解析列表或移动到下个令牌(种类)) {
                    跳出;
                }
            }

            解析语义 = 储存解析语义;
            返回 创建节点数组(列表, 列表首位);
        }

        函数 解析列表元素<T 扩展 节点_>(语义: 解析语义_, 解析元素: () => T): T {
            常量 n = 当前节点(语义);
            如果 (n) {
                返回 <T>消耗节点(n);
            }

            返回 解析元素();
        }

        函数 当前节点(语义: 解析语义_): 节点_ | 未定 {
            如果 (解析错误下个节点完成之前) {
                返回 未定;
            }

            如果 (!语法光标) {
                返回 未定;
            }

            常量 n = 语法光标.当前节点(扫描器.获取开始首位());

            如果 (节点是失踪(n)) {
                返回 未定;
            }

            如果 (n.相交改变) {
                返回 未定;
            }

            如果 (包含分析错误(n)) {
                返回 未定;
            }

            常量 节点语义标志 = n.标志 & 节点标志_.下文标志_;
            如果 (节点语义标志 !== 节点语义标志) {
                返回 未定;
            }

            如果 (!可以重用节点(n, 语义)) {
                返回 未定;
            }

            如果 ((n 转为 JSDoc容器_).jsDoc缓存_) {
                (n 转为 JSDoc容器_).jsDoc缓存_ = 未定;
            }

            返回 n;
        }

        函数 消耗节点(n: 节点_) {
            扫描器.设置文本首位(n.尾位);
            下个令牌();
            返回 n;
        }

        函数 可以重用节点(n: 节点_, 语义: 解析语义_): 真假 {
            假如 (语义) {
                若是 解析语义_.假如子句_:
                    返回 是可重假如子句(n);
                若是 解析语义_.源码元素_:
                若是 解析语义_.跳出语句_:
                若是 解析语义_.假如若是语句_:
                    返回 是可重语句(n);
                若是 解析语义_.参数声明_:
                    返回 !!是可重用参数(n);
                若是 解析语义_.实参表达式_:
            }
            返回 为假;
        }

        函数 是可重假如子句(n: 节点_) {
            如果 (n) {
                假如 (n.种类) {
                    若是 语法_.若是子句_:
                    若是 语法_.默认子句_:
                        返回 为真;
                }
            }
            返回 为假;
        }

        函数 是可重语句(n: 节点_) {
            如果 (n) {
                假如 (n.种类) {
                    若是 语法_.函数声明_:
                    若是 语法_.方法声明_:
                    若是 语法_.变量语句_:
                    若是 语法_.简洁变量语句_:
                    若是 语法_.常量语句_:
                    若是 语法_.块_:
                    若是 语法_.如果语句_:
                    若是 语法_.表达式语句_:
                    若是 语法_.返回语句_:
                    若是 语法_.假如语句_:
                    若是 语法_.跳出语句_:
                    若是 语法_.继续语句_:
                    若是 语法_.贯穿语句_:
                    若是 语法_.删除语句_:
                    若是 语法_.初始函数声明_:
                    若是 语法_.执行语句_:
                    若是 语法_.循环属于语句_:
                    若是 语法_.循环语句_:
                    若是 语法_.循环属于语句_:
                    若是 语法_.空语句_:
                    若是 语法_.标签语句_:
                    若是 语法_.调试语句_:
                    若是 语法_.接口声明_:
                    若是 语法_.结构声明_:
                    若是 语法_.类型别名声明_:
                    若是 语法_.类型声明_:
                        返回 为真;
                }
            }
            返回 为假;
        }

        函数 是可重用参数(n: 节点_) {
            如果 (n.种类 !== 语法_.参数_) {
                返回 为假;
            }
            返回 未定;
        }

        函数 终止解析列表或移动到下个令牌(语义: 解析语义_) {
            解析错误在当前令牌(解析语义错误(语义));
            如果 (是在某些解析语义中()) {
                返回 为真;
            }
            下个令牌();
            返回 为假;
        }

        函数 解析逗号列表<T 扩展 节点_>(语义: 解析语义_, 解析元素: () => T, 将分号视为分隔符?: 真假): 节点数组_<T> {
            常量 储存解析语义 = 解析语义;
            解析语义 |= 1 << 语义;
            常量 列表 = [];
            常量 列表首位 = 获取节点首位();

            变量 逗号开始 = -1;
            判断 (为真) {
                如果 (是列表元素(语义, /*在错误恢复*/ 为假)) {
                    常量 开始首位 = 扫描器.获取开始首位();
                    列表.压入(解析列表元素(语义, 解析元素));
                    逗号开始 = 扫描器.获取令牌首位();
                    如果 (解析可选(语法_.逗号_)) {
                        继续;
                    }

                    逗号开始 = -1;
                    如果 (是列表终止(语义)) {
                        跳出;
                    }

                    解析预期(语法_.逗号_);

                    如果 (将分号视为分隔符 && 令牌() === 语法_.分号_ && !扫描器.具有前导换行符()) {
                        下个令牌();
                    }
                    如果 (开始首位 === 扫描器.获取开始首位()) {
                        下个令牌();
                    }
                    继续;
                }

                如果 (是列表终止(语义)) {
                    跳出;
                }

                如果 (终止解析列表或移动到下个令牌(语义)) {
                    跳出;
                }
            }

            解析语义 = 储存解析语义;
            常量 结果 = 创建节点数组(列表, 列表首位);
            如果 (逗号开始 >= 0) {
                结果.有尾随逗号 = 为真;
            }
            返回 结果;
        }

        函数 创建失踪列表<T 扩展 节点_>(): 节点数组_<T> {
            返回 创建节点数组<T>([], 获取节点首位());
        }

        函数 解析实体名称(允许保留字: 真假, 诊断信息?: 诊断信息_): 实体名称_ {
            变量 实体: 实体名称_ = 允许保留字 ? 解析标识符名称(诊断信息) : 解析标识符(诊断信息);
            判断 (解析可选(语法_.点号_)) {
                实体 = 创建限定名(实体, 解析点右侧(允许保留字));
            }
            返回 实体;
        }

        函数 创建限定名(实体: 实体名称_, 名称: 标识符_): 限定名_ {
            常量 n = 创建节点(语法_.限定名_, 实体.首位) 转为 限定名_;
            n.左侧 = 实体;
            n.右侧 = 名称;
            返回 完成节点(n);
        }

        函数 解析点右侧(允许标识符名称: 真假): 标识符_ {
            如果 (扫描器.具有前导换行符() && 令牌是标识符或关键字(令牌())) {
                常量 匹配模式 = 前瞻(下个令牌是在同一行的标识符或关键字);

                如果 (匹配模式) {
                    返回 创建失踪节点<标识符_>(语法_.标识符_, /*报告当前位置*/ 为真, 诊断信息_.应为标识符);
                }
            }

            返回 允许标识符名称 ? 解析标识符名称() : 解析标识符();
        }

        函数 解析模板表达式(): 模板表达式_ {
            常量 模板 = <模板表达式_>创建节点(语法_.模板表达式_);

            模板.头部 = 解析模板头();
            调试_.断言(模板.头部.种类 === 语法_.模板头_, '模板头部有错误的令牌种类.');

            常量 列表 = [];
            常量 列表首位 = 获取节点首位();

            运行 {
                列表.压入(解析模板跨度());
            }
            判断 (最后的(列表).字面量.种类 === 语法_.模板中_);

            模板.模板跨度组 = 创建节点数组(列表, 列表首位);

            返回 完成节点(模板);
        }

        函数 解析模板跨度(): 模板跨度_ {
            常量 跨度 = <模板跨度_>创建节点(语法_.模板跨度_);
            跨度.表达式 = 解析表达式();

            变量 字面量: 模板中_ | 模板尾_;
            如果 (令牌() === 语法_.右大括号_) {
                预扫描模板令牌();
                字面量 = 解析模板中间或模板尾();
            }
            否则 {
                字面量 = <模板尾_>解析预期令牌(语法_.模板尾_, 诊断信息_.应为_0, 令牌转为文字(语法_.右大括号_));
            }

            跨度.字面量 = 字面量;
            返回 完成节点(跨度);
        }

        函数 解析字面量节点(): 字面量表达式_ {
            返回 <字面量表达式_>解析字面量族节点(令牌());
        }

        函数 解析模板头(): 模板头_ {
            常量 片段 = 解析字面量族节点(令牌());
            调试_.断言(片段.种类 === 语法_.模板头_, '模板头部有错误的令牌种类.');
            返回 <模板头_>片段;
        }

        函数 解析模板中间或模板尾(): 模板中_ | 模板尾_ {
            常量 片段 = 解析字面量族节点(令牌());
            调试_.断言(片段.种类 === 语法_.模板中_ || 片段.种类 === 语法_.模板尾_, '模板片段有错误的令牌种类.');
            返回 <模板中_ | 模板尾_>片段;
        }

        /*
        函数 解析数字字面量节点(): 数字字面量_ {
            常量 n = <数字字面量_>创建节点(语法_.数字字面量_);
            常量 文本 = 扫描器.获取令牌值();
            n.文本 = 文本;
            (<数字字面量_>n).数字字面量标志 = 扫描器.获取令牌标志() & 令牌标志_.数字字面量标志_;
            (<数字字面量_>n).是虚部 = !!(扫描器.获取令牌标志() & 令牌标志_.虚部_);
            下个令牌();
            返回 完成节点(n);
        }
        */

        函数 解析字面量族节点(种类: 语法_): 字面量表达式_ | 字面量族节点_ {
            常量 n = <字面量表达式_>创建节点(种类);
            常量 文本 = 扫描器.获取令牌值();
            n.文本 = 文本;

            如果 (扫描器.有扩展万码转义()) {
                n.有扩展万码转义 = 为真;
            }

            如果 (扫描器.是未终止的()) {
                n.是未终止的 = 为真;
            }

            如果 (n.种类 === 语法_.数字字面量_) {
                (<数字字面量_>n).数字字面量标志 = 扫描器.获取令牌标志() & 令牌标志_.数字字面量标志_;
                (<数字字面量_>n).是虚部 = !!(扫描器.获取令牌标志() & 令牌标志_.虚部_);
            }

            如果 (n.种类 === 语法_.字符字面量_) {
                n
            }
            下个令牌();
            完成节点(n);

            返回 n;
        }

        // TYPES
        函数 解析类型引用(): 类型引用节点_ {
            常量 n = <类型引用节点_>创建节点(语法_.类型引用_);
            n.类型名 = 解析实体名称(/*允许保留字*/ 为真, 诊断信息_.应为类型);
            如果 (令牌() === 语法_.左尖号_ && !扫描器.具有前导换行符()) {
                如果 (解析可选(语法_.左尖号_)) {
                    n.类型实参 = 解析逗号列表(解析语义_.类型实参_, 解析类型);
                    解析预期(语法_.右尖号_)
                }
            }
            返回 完成节点(n);
        }

        函数 解析JSDoc函数类型(): 类型引用节点_ {
            常量 n = <类型引用节点_>创建节点(语法_.类型引用_);
            n.类型名 = 解析标识符名称();
            返回 完成节点(n);
        }

        函数 parseTypeParameter(): 类型参数声明_ {
            常量 node = <类型参数声明_>创建节点(语法_.类型参数声明_);
            node.名称 = 解析标识符();
            如果 (解析可选(语法_.冒号_)) {
                // It's not uncommon for people to write improper constraints to a generic.  If the
                // user writes a constraint that is an expression and not an actual type, then parse
                // it out as an expression (so we can recover well), but report that a type is needed
                // instead.
                如果 (是类型开始() || !是表达式开始()) {
                    变量 默认约束 = 解析类型();
                    如果 (解析可选(语法_.问号_)) {
                        变量 真类型 = 解析类型()
                        解析预期(语法_.冒号_)
                        变量 假类型 = 解析类型()
                        变量 条件类型 = <条件类型节点_>创建节点(语法_.条件类型_, node.首位)
                        条件类型.检查类型 = node
                        条件类型.条件类型 = 默认约束
                        条件类型.真类型 = 真类型
                        条件类型.假类型 = 假类型
                        node.约束 = 条件类型
                    }
                    否则 {
                        node.约束 = 默认约束;
                    }
                }
                否则 {
                    // It was not a type, and it looked like an expression.  Parse out an expression
                    // here so we recover well.  Note: it is important that we call parseUnaryExpression
                    // and not parseExpression here.  If the user has:
                    //      <T extends "">
                    // We do *not* want to consume the `>` as we're consuming the expression for "".
                    node.表达式 = 解析一元表达式或更高();
                }
            }
            否则  如果 (解析可选(语法_.问号_)) {
                node.可选 = 为真
                node.默认 = <类型节点_>创建节点(语法_.未定_)
                node.默认.首位 = -1
                node.默认.尾位 = -1
                node.默认.标志 |= 节点标志_.合成的_
            }
            否则 如果 (解析可选(语法_.等号_)) {
                变量 默认类型 = 解析类型()
                如果 (解析可选(语法_.问号_)) {
                    变量 真类型 = 解析类型()
                    解析预期(语法_.冒号_)
                    变量 假类型 = 解析类型()
                    变量 三元类型 = <三元类型节点_>创建节点(语法_.三元类型_, 默认类型.首位)
                    三元类型.条件类型 = 默认类型
                    三元类型.真类型 = 真类型
                    三元类型.假类型 = 假类型
                    完成节点(三元类型)
                    node.默认 = 三元类型;
                }
                否则 {
                    node.默认 = 默认类型;
                }
            }
            返回 完成节点(node);
        }

        函数 parseTypeParameters(): 节点数组_<类型参数声明_> | 未定 {
            如果 (解析可选(语法_.左尖号_)) {
                常量 结果 = 解析逗号列表(解析语义_.类型参数_, parseTypeParameter);
                解析预期(语法_.右尖号_);
                返回 结果;
            }
            返回 创建失踪列表<类型参数声明_>();
        }

        函数 解析类型实参(): 节点数组_<类型节点_> | 未定 {
            如果 (解析可选(语法_.左尖号_)) {
                常量 结果 = 解析逗号列表(解析语义_.类型参数_, 解析类型);
                解析预期(语法_.右尖号_);
                返回 结果;
            }
            返回 创建失踪列表<类型节点_>();
        }

        函数 解析参数类型(): 类型节点_ | 未定 {
            如果 (解析可选(语法_.冒号_)) {
                返回 解析类型();
            }
            返回 未定;
        }

        函数 是参数开始(): 真假 {
            返回 是标识符() || 是类型开始();
        }

        函数 解析方法接收者(): 接受者声明_ {
            常量 n = <接受者声明_>创建节点包括JSDoc(语法_.接受者声明_);
            如果 (解析可选(语法_.星号_)) {
                常量 pn = <指针类型节点_>创建节点(语法_.指针类型_, n.首位);
                常量 tn = <类型引用节点_>创建节点(语法_.类型引用_);
                tn.类型名 = 解析标识符();
                pn.基础类型 = 完成节点(tn);
                n.类型 = 完成节点(pn);
                返回 完成节点(n);
            }
            否则 {
                常量 tn = <类型引用节点_>创建节点(语法_.类型引用_);
                tn.类型名 = 解析标识符();
                n.类型 = 完成节点(tn);
                返回 完成节点(n);
            }
        }

        函数 解析参数元素(): 参数声明_ {
            常量 n = <参数声明_>创建节点包括JSDoc(语法_.参数_);
            n.名称 = 解析标识符名称();
            n.类型 = 解析参数类型();
            返回 完成节点(n);
        }

        函数 解析逗号或分号() {
            如果 (解析可选(语法_.逗号_)) {
                返回;
            }
            解析分号();
        }

        函数 是明确的方法声明(): 真假 {
            下个令牌();
            如果(令牌() === 语法_.左括号_){
                返回 为真
            }
            判断(!扫描器.具有前导换行符()){
                如果(令牌() === 语法_.左括号_){
                    返回 为真
                }
                如果(令牌() === 语法_.文件结尾令牌_){
                    返回 为假
                }
                下个令牌()
            }
            返回 为假;
        }

        函数 解析接口成员(): 类型引用节点_ | 方法签名_ {
            返回 前瞻(是明确的方法声明) ? 解析方法签名() : 解析匿名接口成员()
        }

        函数 解析匿名接口成员() {
            变量 n = 解析类型引用();
            解析逗号或分号();
            返回 完成节点(n);
        }

        函数 解析方法签名(): 方法签名_ {
            变量 n = <方法签名_>创建节点包括JSDoc(语法_.未知_);
            n.种类 = 语法_.方法签名_;
            (<方法签名_>n).名称 = 解析标识符();
            (<方法签名_>n).类型参数 = parseTypeParameters()
            解析预期(语法_.左括号_);
            (<方法签名_>n).参数 = 解析逗号列表(解析语义_.参数声明_, 解析参数元素);
            解析预期(语法_.右括号_);
            如果 (解析可选(语法_.冒号_)) {
                (<方法签名_>n).类型 = 解析返回值声明()
            }
            解析逗号或分号();
            返回 完成节点(n);
        }

        函数 解析接口成员声明(): 节点数组_<类型引用节点_ | 方法签名_> {
            如果 (解析预期(语法_.左大括号_)) {
                变量 成员 = 解析列表(解析语义_.接口成员_, 解析接口成员);
                解析预期(语法_.右大括号_);
                返回 成员;
            }
            否则 {
                返回 创建失踪列表<类型引用节点_ | 方法签名_>();
            }
        }

        函数 解析词典类型(): 词典类型节点_ {
            常量 n = <词典类型节点_>创建节点(语法_.词典类型_);
            解析预期(语法_.左方括号_);
            n.键类型 = 解析类型()
            解析预期(语法_.冒号_)
            n.值类型 = 解析类型()
            解析预期(语法_.右方括号_);
            返回 完成节点(n);
        }

        函数 解析括号类型(): 括号类型节点_ {
            常量 n = <括号类型节点_>创建节点(语法_.括号类型_);
            解析预期(语法_.左括号_);
            n.类型 = 解析类型();
            解析预期(语法_.右括号_);
            返回 完成节点(n);
        }

        函数 解析函数类型(种类: 语法_): 函数类型节点_ {
            常量 n = <函数类型节点_>创建节点包括JSDoc(种类);
            n.类型参数 = parseTypeParameters()
            变量 有括号 = 解析可选(语法_.左括号_);
            n.参数 = 解析逗号列表(解析语义_.参数声明_, 解析参数元素);
            如果 (有括号) {
                解析预期(语法_.右括号_);
            }
            解析预期(语法_.等右尖冒号_);
            (<函数类型节点_>n).类型 = 解析返回值声明();
            返回 完成节点(n);
        }

        函数 解析关键字和非点(): 类型节点_ | 未定 {
            常量 n = 解析令牌节点<类型节点_>();
            返回 令牌() === 语法_.点号_ ? 未定 : n;
        }

        函数 解析非数组类型(): 类型节点_ {
            假如 (令牌()) {
                若是 语法_.类型_:
                若是 语法_.真假_:
                若是 语法_.通用_:
                若是 语法_.整数_:
                若是 语法_.整数8_:
                若是 语法_.整数16_:
                若是 语法_.整数32_:
                若是 语法_.整数64_:
                若是 语法_.正整数_:
                若是 语法_.正整数8_:
                若是 语法_.正整数16_:
                若是 语法_.正整数32_:
                若是 语法_.正整数64_:
                若是 语法_.小数_:
                若是 语法_.小数32_:
                若是 语法_.小数64_:
                若是 语法_.复数64_:
                若是 语法_.复数128_:
                若是 语法_.字节_:
                若是 语法_.字符_:
                若是 语法_.文本_:
                若是 语法_.无值_:
                若是 语法_.未定_:
                    返回 尝试解析(解析关键字和非点) || 解析类型引用();
                若是 语法_.函数_:
                    返回 解析JSDoc函数类型();
                若是 语法_.左方括号_:
                    返回 解析词典类型();
                若是 语法_.左括号_:
                    返回 解析括号类型();
                默认:
                    返回 解析类型引用();
            }
        }

        函数 是类型开始(): 真假 {
            假如 (令牌()) {
                若是 语法_.类型_:
                若是 语法_.真假_:
                若是 语法_.通用_:
                若是 语法_.整数_:
                若是 语法_.整数8_:
                若是 语法_.整数16_:
                若是 语法_.整数32_:
                若是 语法_.整数64_:
                若是 语法_.正整数_:
                若是 语法_.正整数8_:
                若是 语法_.正整数16_:
                若是 语法_.正整数32_:
                若是 语法_.正整数64_:
                若是 语法_.小数_:
                若是 语法_.小数32_:
                若是 语法_.小数64_:
                若是 语法_.复数64_:
                若是 语法_.复数128_:
                若是 语法_.字节_:
                若是 语法_.字符_:
                若是 语法_.文本_:
                若是 语法_.星号_:
                    返回 为真;
                若是 语法_.左括号_:
                    返回 前瞻(是括号或函数类型的开始);
                默认:
                    返回 是标识符();
            }
        }

        函数 是括号或函数类型的开始() {
            下个令牌();
            返回 令牌() === 语法_.右括号_ || 是参数开始() || 是类型开始();
        }

        函数 解析后缀类型或更高(): 类型节点_ {
            变量 类型 = 解析非数组类型();
            判断 (!扫描器.具有前导换行符()) {
                假如 (令牌()) {
                    若是 语法_.左方括号_:
                        {
                            解析预期(语法_.左方括号_);
                            如果 (解析可选(语法_.右方括号_)) {
                                常量 n = 创建节点(语法_.数组类型_, 类型.首位) 转为 数组类型节点_;
                                n.元素类型 = 类型;
                                n.长度 = 未定;
                                类型 = 完成节点(n);
                                跳出;
                            } 否则 如果 (解析可选(语法_.三点号_)) {
                                常量 n = 创建节点(语法_.列表类型_, 类型.首位) 转为 列表类型节点_;
                                n.元素类型 = 类型;
                                解析预期(语法_.右方括号_);
                                类型 = 完成节点(n);
                                跳出;
                            }
                            常量 n = 创建节点(语法_.数组类型_, 类型.首位) 转为 数组类型节点_;
                            n.元素类型 = 类型;
                            n.长度 = 解析表达式();
                            解析预期(语法_.右方括号_);
                            类型 = 完成节点(n);
                        }
                        跳出;
                    若是 语法_.冒右尖号_:
                        {
                            解析预期(语法_.冒右尖号_);
                            常量 n = 创建节点(语法_.通信类型_, 类型.首位) 转为 通信类型节点_;
                            n.元素类型 = 类型;
                            类型 = 完成节点(n);
                        }
                        跳出;
                    若是 语法_.减右尖号_:
                        {
                            解析预期(语法_.减右尖号_);
                            常量 n = 创建节点(语法_.只读通信_, 类型.首位) 转为 只读通信节点_;
                            n.元素类型 = 类型;
                            类型 = 完成节点(n);
                        }
                        跳出;
                    若是 语法_.左尖减号_:
                        {
                            解析预期(语法_.左尖减号_);
                            常量 n = 创建节点(语法_.只写通信_, 类型.首位) 转为 只写通信节点_;
                            n.元素类型 = 类型;
                            类型 = 完成节点(n);
                        }
                        跳出;
                    默认:
                        返回 类型;
                }
            }
            返回 类型;
        }

        函数 解析变长参数类型节点(): 类型节点_ {
            如果 (令牌() === 语法_.三点号_) {
                返回 解析变长参数类型()
            }
            返回 解析前缀类型或更高()
        }

        函数 解析变长参数类型(): 变长参数类型_ {
            常量 n = <变长参数类型_>创建节点(语法_.变长参数类型_);
            下个令牌();
            n.元素类型 = 解析前缀类型或更高();
            返回 完成节点(n)
        }

        函数 解析前缀类型或更高(): 类型节点_ {
            如果 (令牌() === 语法_.星号_) {
                返回 解析指针类型()
            }
            返回 解析后缀类型或更高();
        }

        函数 解析指针类型(): 指针类型节点_ {
            常量 n = <指针类型节点_>创建节点(语法_.指针类型_);
            下个令牌();
            n.基础类型 = 解析前缀类型或更高();
            返回 完成节点(n)
        }

        函数 解析联合或交叉类型(种类: 语法_.联合类型_ | 语法_.交叉类型_, 解析组成类型: () => 类型节点_, 运算符: 语法_.或号_ | 语法_.且号_): 类型节点_ {
            解析可选(运算符);
            变量 类型 = 解析组成类型();
            如果 (令牌() === 运算符) {
                常量 类型组 = [类型];
                判断 (解析可选(运算符)) {
                    类型组.压入(解析组成类型());
                }
                常量 n = <联合类型节点_ | 交叉类型节点_>创建节点(种类, 类型.首位);
                n.类型组 = 创建节点数组(类型组, 类型.首位);
                类型 = 完成节点(n);
            }
            返回 类型;
        }

        函数 解析交叉类型或更高(): 类型节点_{
            返回 解析联合或交叉类型(语法_.交叉类型_ , 解析变长参数类型节点, 语法_.且号_);
        }

        函数 解析联合类型或更高(): 类型节点_ {
            返回 解析联合或交叉类型(语法_.联合类型_, 解析交叉类型或更高, 语法_.或号_);
        }

        函数 是函数类型的开始(): 真假 {
            如果( 令牌() === 语法_.左尖号_){
                返回 为真
            }
            返回 令牌() === 语法_.左括号_ && 前瞻(是明确的函数类型开始);
        }

        函数 是明确的函数类型开始() {
            下个令牌();
            如果 (令牌() === 语法_.右括号_) {
                // ( )
                返回 为真;
            }

            判断 (令牌() !== 语法_.文件结尾令牌_) {
                如果 (令牌() === 语法_.右括号_) {
                    下个令牌();
                    如果 (令牌() === 语法_.等右尖冒号_) {
                        // ( xxx:xx, ss: ss ) =>
                        返回 为真;
                    }
                }
                如果 (扫描器.具有前导换行符()) {
                    返回 为假
                }
                下个令牌();
            }

            返回 为假;
        }

        函数 解析类型(): 类型节点_ {
            返回 解析类型平台();
        }

        函数 解析类型平台(): 类型节点_ {
            如果 (是函数类型的开始()) {
                返回 解析函数类型(语法_.函数类型_);
            }
            返回 解析联合类型或更高();
        }

        // EXPRESSIONS
        函数 是表达式开始(): 真假 {
            假如 (令牌()) {
                若是 语法_.左括号_:
                若是 语法_.函数_:
                若是 语法_.斜杠号_:
                若是 语法_.标识符_:
                若是 语法_.数字字面量_:
                若是 语法_.文本字面量_:
                若是 语法_.字符字面量_:
                若是 语法_.数组字面量表达式_:
                若是 语法_.结构字面量表达式_:
                若是 语法_.词典字面量表达式_:
                若是 语法_.列表字面量表达式_:
                若是 语法_.标记模板表达式_:
                若是 语法_.无替换模板字面量_:
                若是 语法_.模板头_:
                若是 语法_.结构_:
                若是 语法_.左方括号_:
                若是 语法_.真_:
                若是 语法_.假_:
                若是 语法_.未定_:
                若是 语法_.星号_:
                若是 语法_.且号_:
                若是 语法_.减右尖号_:
                若是 语法_.字符_:
                若是 语法_.字节_:
                若是 语法_.加号_:
                若是 语法_.减号_:
                若是 语法_.波折号_:
                若是 语法_.叹号_:
                若是 语法_.创建_:
                若是 语法_.新建_:
                若是 语法_.执行_:
                若是 语法_.善后_:
                若是 语法_.无值_:
                若是 语法_.左尖号_:
                    返回 为真;
                默认:
                    如果 (是二元运算符()) {
                        返回 为真;
                    }
                    返回 是标识符();
            }
        }

        函数 是表达式语句的开始(): 真假 {
            返回 令牌() !== 语法_.左大括号_ &&
                令牌() !== 语法_.函数_ &&
                令牌() !== 语法_.艾特号_ &&
                是表达式开始();
        }

        函数 解析表达式(): 表达式_ {
            返回 解析赋值表达式或更高();
        }

        函数 解析立即调用表达式剩余(表达式: 左侧表达式_): 左侧表达式_ {
            判断 (令牌() === 语法_.左括号_) {
                常量 调用表达式 = <调用表达式_>创建节点(语法_.调用表达式_, 表达式.首位);
                调用表达式.表达式 = 表达式;
                调用表达式.实参组 = 解析实参列表();
                表达式 = 完成节点(调用表达式);
                继续;

            }
            返回 表达式;
        }

        函数 解析赋值表达式或更高(): 表达式_ {
            常量 箭头表达式 = 尝试解析箭头函数表达式();
            如果 (箭头表达式) {
                返回 解析立即调用表达式剩余(箭头表达式);
            }
            常量 表达式 = 解析二元表达式或更高(/*优先级*/ 0);
            如果 (表达式.种类 === 语法_.标识符_ && (令牌() === 语法_.等右尖号_ || 令牌() === 语法_.等右尖冒号_)) {
                返回 解析立即调用表达式剩余(解析简单箭头函数表达式(<标识符_>表达式));
            }

            如果 (令牌() === 语法_.左尖减号_) {
                解析预期(语法_.左尖减号_)
                常量 n = <写入通信表达式_>创建节点(语法_.写入通信表达式_)
                n.左侧 = 表达式;
                n.右侧 = 解析表达式();
                返回 完成节点(n)
            }

            如果 (是左侧表达式(表达式) && 是赋值运算符(预扫描右尖号令牌())) {
                返回 制作二元表达式(表达式, 解析令牌节点(), 解析赋值表达式或更高());
            }

            返回 解析条件表达式剩余(表达式);
        }

        函数 解析结构字面量(): 结构字面量成员表达式_ {
            变量 n = <结构字面量成员表达式_>创建节点(语法_.结构字面量成员表达式_);
            n.名称 = 解析标识符()
            解析预期(语法_.冒号_)
            n.初始化 = <表达式_>解析表达式()
            返回 完成节点(n)
        }

        函数 解析简单箭头函数表达式(标识符: 标识符_): 箭头函数_ {
            调试_.断言(令牌() === 语法_.等右尖号_ || 令牌() === 语法_.等右尖冒号_ , '`解析简单箭头函数表达式`应该被调用如果我们有个 =>');

            变量 n = <箭头函数_>创建节点(语法_.箭头函数_, 标识符.首位);
            常量 参数 = <参数声明_>创建节点(语法_.参数_, 标识符.首位);
            参数.名称 = 标识符;
            完成节点(参数);
            n.参数 = 创建节点数组<参数声明_>([参数], 参数.首位, 参数.尾位);
            如果(令牌() === 语法_.等右尖冒号_){
                n.等右尖号 = 解析预期令牌(语法_.等右尖冒号_);
                (<箭头函数_>n).类型 = 解析返回值声明();
            }
            否则 如果(令牌() === 语法_.等右尖号_){
                n.等右尖号 = 解析预期令牌(语法_.等右尖号_);
            }
            n.主体 = 解析箭头函数表达式主体();
            返回 添加JSDoc注释(完成节点(n));
        }

        函数 尝试解析箭头函数表达式(): 箭头函数_ | 未定 {
            变量 三态 = 是带括号的箭头函数表达式()
            如果 (三态 === 三态_.为假_) 返回 未定
            变量 箭头函数 = 三态 === 三态_.为真_ ?
                解析带括号箭头函数表达式() :
                尝试解析(尝试解析带括号的箭头函数表达式)
            如果 (!箭头函数) {
                返回 未定
            }
            返回 完成节点(箭头函数)
        }

        函数 尝试解析带括号的箭头函数表达式(){
            常量 储存解析诊断信息长度 = 解析诊断信息.长度;
            变量 箭头函数 = 解析带括号箭头函数表达式()
            如果(储存解析诊断信息长度 === 解析诊断信息.长度){
                返回 箭头函数
            }
            返回 未定!
        }

        常量 枚举 三态_ {
            为假_,
            为真_,
            未知_
        }

        函数 是带括号的箭头函数表达式(): 三态_ {
            如果 (令牌() === 语法_.左括号_ || 令牌() === 语法_.左尖号_) {
                返回 前瞻(是带括号的箭头函数表达式平台);
            }
            如果 (令牌() === 语法_.等右尖号_ || 令牌() === 语法_.等右尖冒号_) {
                // ERROR RECOVERY TWEAK:
                // If we see a standalone => try to parse it as an arrow function expression as that's
                // likely what the user intended to write.
                返回 三态_.为真_;
            }

            返回 三态_.为假_;
        }

        函数 是带括号的箭头函数表达式平台(): 三态_ {
            常量  第一个 = 令牌();
            常量 第二个 = 下个令牌();

            如果 (第一个 === 语法_.左括号_) {
                如果 (第二个 === 语法_.右括号_) {
                    // Simple cases: "() =>", "(): ", and "() {".
                    // This is an arrow function with no parameters.
                    // The last one is not actually an arrow function,
                    // but this is probably what the user intended.
                    常量 第三个 = 下个令牌();
                    假如 (第三个) {
                        若是 语法_.等右尖号_:
                        若是 语法_.等右尖冒号_:
                        若是 语法_.冒号_:
                        若是 语法_.左大括号_:
                            返回 三态_.为真_;
                        默认:
                            返回 三态_.为假_;
                    }
                }

                // If encounter "([" or "({", this could be the start of a binding pattern.
                // Examples:
                //      ([ x ]) => { }
                //      ({ x }) => { }
                //      ([ x ])
                //      ({ x })
                如果 (第二个 === 语法_.左方括号_ || 第二个 === 语法_.左大括号_) {
                    返回 三态_.未知_;
                }

                // Simple 若是: "(..."
                // This is an arrow function with a rest parameter.
                如果 (第二个 === 语法_.三点号_) {
                    返回 三态_.为真_;
                }

                
                // If we had "(" followed by something that's not an identifier,
                // then this definitely doesn't look like a lambda.
                如果 (!是标识符()) {
                    返回 三态_.为假_;
                }

                假如 (下个令牌()) {
                    若是 语法_.冒号_:
                        // If we have something like "(a:", then we must have a
                        // type-annotated parameter in an arrow function expression.
                        返回 三态_.为真_;
                    若是 语法_.问号_:
                    下个令牌();
                        // If we have "(a?:" or "(a?," or "(a?=" or "(a?)" then it is definitely a lambda.
                        如果 (令牌() === 语法_.冒号_ || 令牌() === 语法_.逗号_ || 令牌() === 语法_.等号_ || 令牌() === 语法_.右括号_) {
                            返回 三态_.为真_;
                        }
                        // Otherwise it is definitely not a lambda.
                        返回 三态_.为假_;
                    若是 语法_.逗号_:
                    若是 语法_.等号_:
                    若是 语法_.右括号_:
                        // If we have "(a," or "(a=" or "(a)" this *could* be an arrow function
                        返回 三态_.未知_;
                }
                // It is definitely not an arrow function
                返回 三态_.为假_;
            }
            否则 {
                调试_.断言(第一个 === 语法_.左尖号_);

                // If we have "<" not followed by an identifier,
                // then this definitely is not an arrow function.
                如果 (!是标识符()) {
                    返回 三态_.为假_;
                }
                // This *could* be a parenthesized arrow function.
                返回 三态_.未知_;
            }
        }

        函数 解析带括号箭头函数表达式(): 箭头函数_ {
            常量 n = <箭头函数_>创建节点包括JSDoc(语法_.箭头函数_);
            n.类型参数 = parseTypeParameters()
            变量 有括号 = 解析可选(语法_.左括号_);
            n.参数 = 解析逗号列表(解析语义_.参数声明_, 解析参数元素);
            如果 (有括号) {
                解析预期(语法_.右括号_);
            }
            如果(令牌() === 语法_.等右尖冒号_){
                n.等右尖号 = 解析预期令牌(语法_.等右尖冒号_);
                (<箭头函数_>n).类型 = 解析返回值声明();
            }
            否则 如果(令牌() === 语法_.等右尖号_){
                n.等右尖号 = 解析预期令牌(语法_.等右尖号_);
            }
            n.主体 = 解析箭头函数表达式主体();
            返回 完成节点(n);
        }

        函数 解析箭头函数表达式主体(): 块_ | 表达式_ {
            如果 (令牌() === 语法_.左大括号_) {
                返回 解析函数主体(签名标志_.无_);
            }
            如果 (令牌() !== 语法_.分号_ &&
                令牌() !== 语法_.函数_ &&
                是语句开始() &&
                !是表达式语句的开始()) {
                返回 解析函数主体(签名标志_.忽略失踪大括号_ | 签名标志_.无_);
            }
            返回 解析赋值表达式或更高();
        }

        函数 解析条件表达式剩余(左侧运算符: 表达式_): 表达式_ {
            常量 问号 = 解析可选令牌(语法_.问号_);
            如果 (!问号) {
                返回 左侧运算符;
            }
            常量 n = <条件表达式_>创建节点(语法_.条件表达式_, 左侧运算符.首位);
            n.条件 = 左侧运算符;
            n.问号 = 问号;
            n.当为真 = 解析赋值表达式或更高();
            n.冒号 = 解析预期令牌(语法_.冒号_);
            n.当为假 = 节点是存在的(n.冒号)
                ? 解析赋值表达式或更高()
                : 创建失踪节点(语法_.标识符_, /*报告当前位置*/ 为假, 诊断信息_.应为_0, 令牌转为文字(语法_.冒号_));
            返回 完成节点(n);
        }

        函数 解析二元表达式或更高(优先级: 数字): 表达式_ {
            常量 左侧运算符 = 解析一元表达式或更高();
            返回 解析二元表达式剩余(优先级, 左侧运算符);
        }

        函数 解析二元表达式剩余(优先级: 数字, 左侧运算符: 表达式_): 表达式_ {
            判断 (为真) {
                预扫描右尖号令牌();
                常量 新优先级 = 获取二元运算符优先级();

                常量 消耗当前运算符 = 新优先级 > 优先级;
                如果 (!消耗当前运算符) {
                    跳出;
                }
                如果 (令牌() === 语法_.星号_ && 扫描器.具有前导换行符() && 前瞻(解析标识符名称)) {
                    跳出;
                }
                左侧运算符 = 制作二元表达式(左侧运算符, 解析令牌节点(), 解析二元表达式或更高(新优先级));
            }

            返回 左侧运算符;
        }

        函数 是二元运算符() {
            返回 获取二元运算符优先级() > 4;
        }

        函数 获取二元运算符优先级(): 数字 {
            假如 (令牌()) {
                若是 语法_.双或号_:
                    返回 5;
                若是 语法_.双且号_:
                    返回 6;
                若是 语法_.或号_:
                    返回 7;
                若是 语法_.异或号_:
                    返回 8;
                若是 语法_.且号_:
                    返回 9;
                若是 语法_.双等号_:
                若是 语法_.叹号等号_:
                    返回 10;
                若是 语法_.左尖号_:
                若是 语法_.右尖号_:
                若是 语法_.左尖等号_:
                若是 语法_.右尖等号_:
                若是 语法_.位于_:
                    返回 11;
                若是 语法_.双左尖号_:
                若是 语法_.双右尖号_:
                    返回 12;
                若是 语法_.加号_:
                若是 语法_.减号_:
                    返回 13;
                若是 语法_.星号_:
                若是 语法_.斜杠号_:
                若是 语法_.百分号_:
                    返回 14;
            }
            返回 -1;
        }

        函数 制作二元表达式(左侧: 表达式_, 运算符: 二元运算符令牌_, 右侧: 表达式_): 二元表达式_ {
            常量 n = <二元表达式_>创建节点(语法_.二元表达式_, 左侧.首位);
            n.左侧 = 左侧;
            n.运算符令牌 = 运算符;
            n.右侧 = 右侧;
            返回 完成节点(n);
        }

        函数 解析前缀一元表达式() {
            常量 n = <前缀一元表达式_>创建节点(语法_.前缀一元表达式_);
            n.运算符 = <前缀一元运算符_>令牌();
            下个令牌();
            n.算子 = 解析简单一元表达式();

            返回 完成节点(n);
        }

        函数 解析无值表达式() {
            常量 n = <无值表达式_>创建节点(语法_.无值表达式_);
            下个令牌();
            n.表达式 = 解析简单一元表达式();
            返回 完成节点(n);
        }
        函数 解析一元表达式或更高(): 一元表达式_ | 二元表达式_ {
            如果 (是更新表达式()) {
                返回 解析更新表达式();
            }
            返回 解析简单一元表达式();
        }

        函数 解析简单一元表达式(): 一元表达式_ {
            假如 (令牌()) {
                若是 语法_.加号_:
                若是 语法_.减号_:
                若是 语法_.波折号_:
                若是 语法_.叹号_:
                    返回 解析前缀一元表达式();
                若是 语法_.无值_:
                    返回 解析无值表达式();
                默认:
                    返回 解析更新表达式();
            }
        }

        函数 是更新表达式(): 真假 {
            假如 (令牌()) {
                若是 语法_.星号_:
                若是 语法_.且号_:
                若是 语法_.加号_:
                若是 语法_.减号_:
                若是 语法_.波折号_:
                若是 语法_.叹号_:
                若是 语法_.无值_:
                若是 语法_.左尖号_:
                    返回 为假;
                默认:
                    返回 为真;
            }
        }

        函数 解析更新表达式(): 更新表达式_ {
            如果 (令牌() === 语法_.星号_) {
                常量 n = <取值表达式_>创建节点(语法_.取值表达式_);
                n.运算符 = 语法_.星号_;
                下个令牌();
                n.算子 = 解析左侧表达式或更高();
                返回 完成节点(n);
            }
            如果 (令牌() === 语法_.且号_) {
                常量 n = <取址表达式_>创建节点(语法_.取址表达式_);
                n.运算符 = 语法_.且号_;
                下个令牌();
                n.算子 = 解析左侧表达式或更高();
                返回 完成节点(n);
            }

            常量 表达式 = 解析左侧表达式或更高();

            // 调试_.断言(是左侧表达式(表达式) || 是创新或新建表达式(表达式) || 是类型断言或类型查询表达式(表达式) || 是简介变量声明赋值表达式_(表达式));
            如果 (令牌() === 语法_.减右尖号_) {
                常量 n = <后缀读信道表达式_>创建节点(语法_.后缀读信道表达式_, 表达式.首位);
                n.算子 = 表达式;
                n.运算符 = <语法_.减右尖号_>令牌();
                下个令牌();
                返回 完成节点(n);
            }
            如果 ((令牌() === 语法_.双加号_ || 令牌() === 语法_.双减号_) && !扫描器.具有前导换行符()) {
                常量 n = <后缀一元表达式_>创建节点(语法_.后缀一元表达式_, 表达式.首位);
                n.算子 = 表达式;
                n.运算符 = <后缀一元运算符_>令牌();
                下个令牌();
                返回 完成节点(n);
            }

            返回 表达式;
        }

        函数 解析左侧表达式或更高(): 左侧表达式_ {
            变量 表达式 = 解析成员表达式或更高();
            返回 解析调用表达式剩余(表达式);
        }

        函数 解析成员表达式或更高(): 成员表达式_ {
            常量 表达式 = 解析基本表达式();
            返回 解析成员表达式剩余(表达式);
        }

        函数 解析成员表达式剩余(表达式: 左侧表达式_): 成员表达式_ {
            判断 (为真) {
                如果(解析可选(语法_.左尖号_)){
                    常量 n = <表达式包括类型参数_>创建节点(语法_.表达式包括类型参数_, 表达式.首位)
                    n.表达式 = 表达式
                    n.类型实参 = 解析逗号列表(解析语义_.类型参数_,解析类型)
                    解析预期(语法_.右尖号_)
                    表达式 = 完成节点(n)
                    继续;
                }

                如果(解析可选令牌(语法_.问点号_)){                    
                    常量 属性访问 = <属性访问表达式_>创建节点(语法_.属性访问表达式_, 表达式.首位);
                    属性访问.表达式 = 表达式;
                    属性访问.问号 =  语法_.问号_
                    属性访问.名称 = 解析点右侧(/*允许标识符名称*/ 为真);
                    表达式 = 完成节点(属性访问);
                    继续;
                }
                否则 如果 (解析可选令牌(语法_.点号_)) {
                    如果 (解析可选令牌(语法_.左尖号_)) {
                        如果 (解析可选令牌(语法_.类型_)) {
                            // 类型查询
                            常量 类型查询 = <类型查询表达式_>创建节点(语法_.类型查询表达式_, 表达式.首位);
                            类型查询.类型 = 语法_.类型_;
                            解析预期(语法_.右尖号_);
                            类型查询.表达式 = 表达式;
                            表达式 = 完成节点(类型查询);
                            继续;
                        }
                        // 类型断言
                        常量 类型断言 = <类型断言表达式_>创建节点(语法_.类型断言表达式_, 表达式.首位);
                        类型断言.类型 = 解析类型();
                        类型断言.表达式 = 表达式;
                        解析预期(语法_.右尖号_)
                        表达式 = 完成节点(类型断言);
                        继续;
                    }
                    如果 (解析可选令牌(语法_.左括号_)) {
                        常量 n = <类型转换表达式_>创建节点(语法_.类型转换表达式_, 表达式.首位);
                        n.表达式 = 解析表达式()
                        n.类型 = <类型节点_><表达式包括类型参数_>表达式
                        解析预期(语法_.右括号_);
                        表达式 = 完成节点(n)
                        继续;
                    }
                    常量 属性访问 = <属性访问表达式_>创建节点(语法_.属性访问表达式_, 表达式.首位);
                    属性访问.表达式 = 表达式;
                    属性访问.名称 = 解析点右侧(/*允许标识符名称*/ 为真);
                    表达式 = 完成节点(属性访问);
                    继续;
                }
                如果 (令牌() === 语法_.无替换模板字面量_ || 令牌() === 语法_.模板头_) {
                    常量 标签表达式 = <标记模板表达式_>创建节点(语法_.标记模板表达式_, 表达式.首位);
                    标签表达式.标签 = 表达式;
                    标签表达式.模板 = 令牌() === 语法_.无替换模板字面量_
                        ? <无替换模板字面量_>解析字面量节点()
                        : 解析模板表达式();
                    表达式 = 完成节点(标签表达式);
                    继续;
                }
                如果(解析可选(语法_.问左方括号_)){
                    常量 索引访问 = <元素访问表达式_>创建节点(语法_.元素访问表达式_, 表达式.首位);
                    索引访问.表达式 = 表达式;
                    索引访问.问号 = 语法_.问号_
                    如果 (令牌() === 语法_.右方括号_) {
                        索引访问.参数表达式 = 创建失踪节点(语法_.标识符_, /*报告在当前位置*/ 为真, 诊断信息_.元素访问表达式应采用参数) 转为 表达式_;
                    }
                    否则 {
                        常量 实参 = 解析表达式();
                        如果 (是文本字面量(实参) || 是数字字面量(实参)) {
                            实参.文本 = 初始化标识符(实参.文本);
                        }
                        索引访问.参数表达式 = 实参;
                    }
                    解析预期(语法_.右方括号_);
                    表达式 = 完成节点(索引访问);
                    继续;
                }
                如果 (解析可选(语法_.左方括号_)) {
                    常量 索引访问 = <元素访问表达式_>创建节点(语法_.元素访问表达式_, 表达式.首位);
                    索引访问.表达式 = 表达式;

                    如果 (令牌() === 语法_.右方括号_) {
                        索引访问.参数表达式 = 创建失踪节点(语法_.标识符_, /*报告在当前位置*/ 为真, 诊断信息_.元素访问表达式应采用参数) 转为 表达式_;
                    }
                    否则 {
                        常量 实参 = 解析表达式();
                        如果 (是文本字面量(实参) || 是数字字面量(实参)) {
                            实参.文本 = 初始化标识符(实参.文本);
                        }
                        索引访问.参数表达式 = 实参;
                    }
                    解析预期(语法_.右方括号_);
                    表达式 = 完成节点(索引访问);
                    继续;
                }

                如果 (解析可选(语法_.左大括号_)) {
                    // 结构字面量 不支持  ?属性断言表达式
                    常量 n = <结构字面量表达式_>创建节点(语法_.结构字面量表达式_, 表达式.首位)                    
                    n.结构体类型名 = <类型引用节点_>创建节点(语法_.类型引用_, 表达式.首位);
                    n.结构体类型名.类型名 = ts.是表达式包括类型参数(表达式)?  <标识符_ | 限定名_>表达式.表达式 : <标识符_ | 限定名_>表达式
                    n.结构体类型名.类型实参 =  ts.是表达式包括类型参数(表达式)? 表达式.类型实参: 未定
                    n.结构体类型名.尾位 = 表达式.尾位

                    n.属性组 = 解析逗号列表(解析语义_.结构字面量成员_, 解析结构字面量)
                    解析预期(语法_.右大括号_)
                    表达式 = 完成节点(n)
                    继续
                }
                返回 <成员表达式_>表达式;
            }
        }

        函数 解析调用表达式剩余(表达式: 左侧表达式_): 左侧表达式_ {
            判断 (为真) {
                表达式 = 解析成员表达式剩余(表达式);
                如果 (令牌() === 语法_.左尖号_) {
                    常量 typeArguments = 尝试解析(parseTypeArgumentsInExpression)
                    如果 (!typeArguments) {
                        返回 表达式;
                    }
                    常量 调用表达式 = <调用表达式_>创建节点(语法_.调用表达式_, 表达式.首位);
                    调用表达式.表达式 = 表达式;
                    调用表达式.类型实参 = typeArguments
                    调用表达式.实参组 = 解析实参列表();
                    表达式 = 完成节点(调用表达式);
                    继续;
                }
                如果 (令牌() === 语法_.左括号_) {
                    常量 调用表达式 = <调用表达式_>创建节点(语法_.调用表达式_, 表达式.首位);
                    调用表达式.表达式 = 表达式;
                    调用表达式.实参组 = 解析实参列表();
                    表达式 = 完成节点(调用表达式);
                    继续;
                }

                返回 表达式;
            }
        }

        函数 parseTypeArgumentsInExpression() {
            如果 (!解析可选(语法_.左尖号_)) {
                返回 未定;
            }

            常量 typeArguments = 解析逗号列表(解析语义_.类型实参_, 解析类型);
            如果 (!解析预期(语法_.右尖号_)) {
                // If it doesn't have the closing `>` then it's definitely not an type argument list.
                返回 未定;
            }

            // If we have a '<', then only parse this as a argument list 如果 the type arguments
            // are complete and we have an open paren.  如果 we don't, rewind and 返回 nothing.
            返回 typeArguments && canFollowTypeArgumentsInExpression()
                ? typeArguments
                : 未定;
        }

        函数 canFollowTypeArgumentsInExpression(): 真假 {
            假如 (令牌()) {
                若是 语法_.左括号_:                 // foo<x>(
                // this 若是 are the only 若是 where this token can legally follow a type argument
                // list.  So we definitely want to treat this as a type arg list.

                若是 语法_.点号_:                       // foo<x>.
                若是 语法_.右括号_:                // foo<x>)
                若是 语法_.右方括号_:              // foo<x>]
                若是 语法_.冒号_:                     // foo<x>:
                若是 语法_.分号_:                 // foo<x>;
                若是 语法_.问号_:                  // foo<x>?
                若是 语法_.双等号_:              // foo<x> ==
                若是 语法_.叹号等号_:         // foo<x> !=
                若是 语法_.双且号_:        // foo<x> &&
                若是 语法_.双或号_:                    // foo<x> ||
                若是 语法_.异或号_:                     // foo<x> ^
                若是 语法_.且号_:                 // foo<x> &
                若是 语法_.或号_:                       // foo<x> |
                若是 语法_.右大括号_:                // foo<x> }
                若是 语法_.文件结尾令牌_:                 // foo<x>
                    // these cases can't legally follow a type arg list.  However, they're not legal
                    // expressions either.  The user is probably in the middle of a generic type. So
                    // treat it as such.
                    返回 为真;

                若是 语法_.逗号_:                     // foo<x>,
                若是 语法_.左大括号_:                 // foo<x> {
                // We don't want to treat these as type arguments.  Otherwise we'll parse this
                // as an invocation expression.  Instead, we want to parse out the expression
                // in isolation from the type arguments.

                默认:
                    // Anything else treat as an expression.
                    返回 为假;
            }
        }

        函数 解析实参列表() {
            解析预期(语法_.左括号_);
            常量 结果 = 解析逗号列表(解析语义_.实参表达式_, 解析实参表达式);
            解析预期(语法_.右括号_);
            返回 结果;
        }

        函数 解析基本表达式(): 基本表达式_ {
            假如 (令牌()) {
                若是 语法_.数字字面量_:
                若是 语法_.文本字面量_:
                若是 语法_.无替换模板字面量_:
                若是 语法_.字符字面量_:
                    返回 解析字面量节点();
                若是 语法_.未定_:
                若是 语法_.无值_:
                若是 语法_.真_:
                若是 语法_.假_:
                    返回 解析令牌节点<基本表达式_>();
                若是 语法_.左括号_:
                    返回 解析括号表达式();
                若是 语法_.创建_:
                    返回 解析创建表达式()
                若是 语法_.函数_:
                    返回 解析函数表达式();
                若是 语法_.新建_:
                    返回 解析新建表达式();
                若是 语法_.斜杠号_:
                    如果 (预扫描斜杠号令牌() === 语法_.正则表达式字面量_) {
                        返回 解析字面量节点();
                    }
                    跳出;
                若是 语法_.模板头_:
                    返回 解析模板表达式();
                若是 语法_.左大括号_:
                    返回 解析列表和词典字面量元素表达式()

            }

            如果 (前瞻(前方是字面量表达式)) {
                常量 n = <列表字面量表达式_ | 数组字面量表达式_ | 词典字面量表达式_>创建节点(语法_.数组字面量表达式_)
                常量 tn = n.元素类型 = 解析类型()
                如果 (是数组类型节点(tn)) {
                    n.种类 = 语法_.数组字面量表达式_
                }
                如果 (是列表类型节点(tn)) {
                    n.种类 = 语法_.列表字面量表达式_
                }
                如果 (是词典类型节点(tn)) {
                    n.种类 = 语法_.词典字面量表达式_
                    解析预期(语法_.左大括号_)
                    n.元素 = 解析逗号列表(解析语义_.词典字面量表达式_, 解析词典键值对)
                    解析预期(语法_.右大括号_)
                    返回 完成节点(n);
                }
                解析预期(语法_.左大括号_)
                n.元素 = 解析逗号列表(解析语义_.数组列表成员_, 解析表达式);
                解析预期(语法_.右大括号_)
                返回 完成节点(n);
            }

            返回 解析标识符名称(诊断信息_.应为表达式);
        }

        函数 前方是字面量表达式() {
            如果 (令牌() !== 语法_.左方括号_) {
                下个令牌()
            }
            如果 (令牌() === 语法_.左方括号_) {
                变量 看见右方括号 = 0;
                变量 看见左方括号 = 0;
                判断 (令牌() !== 语法_.文件结尾令牌_) {
                    如果 (扫描器.具有前导换行符()) {
                        返回 为假;
                    }
                    如果 (令牌() === 语法_.右方括号_) {
                        看见右方括号++
                        下个令牌()
                        如果 (令牌() === 语法_.左大括号_) {
                            如果 (看见右方括号 === 看见左方括号) {
                                返回 为真
                            }
                            返回 为假;
                        }
                        继续
                    }
                    如果 (令牌() === 语法_.左方括号_) {
                        看见左方括号++
                    }
                    下个令牌()
                }
            }
            返回 为假
        }

        函数 是词典类型节点(n: 节点_): n 作为 词典类型节点_ {
            返回 n.种类 === 语法_.词典类型_
        }

        函数 是列表类型节点(n: 节点_): n 作为 列表类型节点_ {
            返回 n.种类 === 语法_.列表类型_
        }

        函数 是数组类型节点(n: 节点_): n 作为 列表类型节点_ {
            返回 n.种类 === 语法_.数组类型_
        }

        函数 解析列表和词典字面量元素表达式(): 数组或列表字面量表达式_ | 词典字面量表达式_ {
            常量 n = <数组或列表字面量表达式_ | 词典字面量表达式_>创建节点(语法_.未知_);
            n.种类 = 语法_.词典字面量表达式_;
            如果 (大括号内是字典字面量表达式()) {
                解析预期(语法_.左大括号_);
                (<词典字面量表达式_>n).元素 = 解析逗号列表(解析语义_.词典字面量表达式_, 解析词典键值对);
                解析预期(语法_.右大括号_);
                返回 完成节点(n);
            }
            否则 {
                解析预期(语法_.左大括号_);
                n.种类 = 语法_.数组或列表字面量表达式_;
                (<数组或列表字面量表达式_>n).元素 = 解析逗号列表(解析语义_.数组列表成员_, 解析表达式);
                解析预期(语法_.右大括号_);
                返回 完成节点(n);
            }
        }

        函数 解析词典键值对(): 词典键值表达式_ {
            常量 n = <词典键值表达式_>创建节点(语法_.词典键值表达式_);
            n.键表达式 = 解析表达式()
            解析预期(语法_.冒号_)
            n.值表达式 = 解析表达式()
            返回 完成节点(n);
        }

        函数 大括号内是字典字面量表达式() {
            返回 前瞻(可以编译键值表达式)
        }

        函数 可以编译键值表达式() {
            下个令牌();
            常量 上个错误数量 = 解析诊断信息.长度;
            解析表达式();
            返回 令牌() === 语法_.冒号_ && 上个错误数量 === 解析诊断信息.长度
        }

        函数 解析创建表达式(): 创建表达式_ {
            常量 n = <创建表达式_>创建节点(语法_.创建表达式_);
            解析预期(语法_.创建_);
            n.类型实参 = 尝试解析(解析类型实参)
            解析预期(语法_.左括号_);
            n.实参1 = 解析表达式();
            如果 (解析可选(语法_.逗号_)) {
                n.实参2 = 解析表达式();
            }
            解析预期(语法_.右括号_);
            返回 完成节点(n);
        }

        函数 解析新建表达式(): 新建表达式_ {
            常量 n = <新建表达式_>创建节点(语法_.新建表达式_);
            解析预期(语法_.新建_)
            n.类型参数 = 解析类型()
            n.类型实参 = 尝试解析(parseTypeArgumentsInExpression)
            解析分号()
            返回 完成节点(n)
        }

        函数 解析括号表达式(): 括号表达式_ {
            常量 n = <括号表达式_>创建节点包括JSDoc(语法_.括号表达式_);
            解析预期(语法_.左括号_);
            n.表达式 = 解析表达式();
            解析预期(语法_.右括号_);
            返回 完成节点(n);
        }

        函数 解析展开元素(): 表达式_ {
            常量 n = <展开元素_>创建节点(语法_.展开元素_);
            解析预期(语法_.三点号_);
            n.表达式 = 解析赋值表达式或更高();
            返回 完成节点(n);
        }

        函数 解析实参或数组字面量元素(): 表达式_ {
            返回 令牌() === 语法_.三点号_ ? 解析展开元素() : 令牌() === 语法_.逗号_ ? <表达式_>创建节点(语法_.省略表达式_) : 解析赋值表达式或更高();
        }

        函数 解析实参表达式(): 表达式_ {
            返回 解析实参或数组字面量元素();
        }

        函数 解析函数表达式(): 函数表达式_ {
            常量 n = <函数表达式_>创建节点包括JSDoc(语法_.函数表达式_);
            解析预期(语法_.函数_);
            n.名称 = 解析可选标识符();
            解析预期(语法_.左括号_);
            n.参数 = 解析逗号列表(解析语义_.参数声明_, 解析参数元素);
            解析预期(语法_.右括号_);
            如果 (解析可选(语法_.冒号_)) {
                n.类型 = 解析返回值声明();
            }
            n.主体 = 解析块(为假, 诊断信息_.应为_或);
            返回 完成节点(n);
        }

        函数 解析可选标识符(): 标识符_ | 未定 {
            返回 是标识符() ? 解析标识符() : 未定;
        }

        // STATEMENTS
        函数 解析块(忽略失踪大括号: 真假, 诊断信息?: 诊断信息_): 块_ {
            常量 n = <块_>创建节点(语法_.块_);
            如果 (解析预期(语法_.左大括号_, 诊断信息) || 忽略失踪大括号) {
                如果 (扫描器.具有前导换行符()) {
                    n.多行 = 为真;
                }

                n.语句组 = 解析列表(解析语义_.跳出语句_, 解析语句);
                解析预期(语法_.右大括号_);
            }
            否则 {
                n.语句组 = 创建失踪列表<语句_>();
            }
            返回 完成节点(n);
        }

        函数 解析函数主体(标志: 签名标志_, 诊断信息?: 诊断信息_): 块_ {
            返回 解析块(!!(标志 & 签名标志_.忽略失踪大括号_), 诊断信息);
        }

        函数 解析空语句(): 语句_ {
            常量 n = <语句_>创建节点(语法_.空语句_);
            解析预期(语法_.分号_);
            返回 完成节点(n);
        }

        函数 解析如果及另如否则语句(语法 = 语法_.如果_): 如果语句_ | 另如语句_ {
            常量 n = <如果语句_ | 另如语句_>创建节点(语法 === 语法_.如果_ ? 语法_.如果语句_ : 语法_.另如语句_);
            解析预期(语法);
            解析预期(语法_.左括号_);
            n.表达式 = 解析表达式();
            解析预期(语法_.右括号_);
            n.然后语句 = 解析语句();
            如果 (令牌() === 语法_.另如_) {
                (<如果语句_ | 另如语句_>n).另如语句 = 解析如果及另如否则语句(语法_.另如_) 转为 另如语句_
            }
            否则 如果 (解析可选(语法_.否则_)) {
                n.否则语句 = 解析语句();
            }
            返回 完成节点(n);
        }

        函数 前方有循环体内属于令牌() {
            返回 前瞻(前瞻属于关键字);
        }

        函数 前瞻属于关键字() {
            变量 t = 扫描器.具有前导换行符() ? 下个令牌() : 令牌()
            判断 (t !== 语法_.右括号_ && t !== 语法_.文件结尾令牌_ && !扫描器.具有前导换行符()) {
                如果 (t === 语法_.属于_) {
                    返回 为真
                }
                t = 下个令牌()
            }
            返回 为假
        }

        函数 前方有循环体内分号令牌() {
            返回 前瞻(前瞻分号令牌)
        }

        函数 前瞻分号令牌() {
            变量 t = 扫描器.具有前导换行符() ? 下个令牌() : 令牌()
            判断 (t !== 语法_.文件结尾令牌_ && !扫描器.具有前导换行符()) {
                如果 (t === 语法_.分号_) {
                    返回 为真
                }
                t = 下个令牌()
            }
            返回 为假
        }

        函数 解析循环语句(): 循环语句_ | 循环属于语句_ {
            变量 n = <循环语句_ | 循环属于语句_>创建节点(语法_.未知_);
            n.种类 = 语法_.循环语句_;
            解析预期(语法_.循环_);
            解析预期(语法_.左括号_);
            // 直接排除 空 循环
            如果 (!解析可选(语法_.右括号_)) {
                如果 (前方有循环体内属于令牌()) {
                    (<循环属于语句_>n).种类 = 语法_.循环属于语句_;
                    (<循环属于语句_>n).声明组 = 解析逗号列表(解析语义_.循环属于声明_, 解析循环属于变量声明)
                    解析预期(语法_.属于_);
                    (<循环属于语句_>n).表达式 = 解析表达式()
                    解析预期(语法_.右括号_);
                }
                否则 如果 (前方有循环体内分号令牌()) {
                    如果 (!解析可选(语法_.分号_)) {
                        (<循环语句_>n).初始化 = 解析简洁变量声明();
                        解析可选(语法_.分号_)
                    }
                    如果 (前方有循环体内分号令牌()) {
                        如果 (!解析可选(语法_.分号_)) {
                            (<循环语句_>n).条件 = 解析表达式();
                            解析可选(语法_.分号_);
                        }
                        如果 (!解析可选(语法_.右括号_)) {
                            (<循环语句_>n).增量器 = 解析逗号列表(解析语义_.循环增量语句块_, 解析赋值表达式或更高);
                            解析预期(语法_.右括号_);
                        }
                    }
                    否则 {
                        如果 (!解析可选(语法_.右括号_)) {
                            (<循环语句_>n).条件 = 解析表达式();
                            解析预期(语法_.右括号_);
                        }
                    }
                }
                否则 {
                    如果 (!解析可选(语法_.右括号_)) {
                        (<循环语句_>n).初始化 = 解析简洁变量声明(为假);
                        解析预期(语法_.右括号_);
                    }
                }
            }
            (<循环语句_ | 循环属于语句_>n).迭代体 = 解析块(为假);
            返回 完成节点(n);
        }

        函数 解析贯穿语句(): 贯穿语句_ {
            常量 n = <贯穿语句_>创建节点(语法_.贯穿语句_);
            解析预期(语法_.贯穿_);
            解析分号();
            返回 完成节点(n);
        }

        函数 解析跳出或继续语句(种类: 语法_): 跳出或继续语句_ {
            常量 n = <跳出或继续语句_>创建节点(种类);
            解析预期(种类 === 语法_.跳出语句_ ? 语法_.跳出_ : 语法_.继续_);
            如果 (!可以解析分号()) {
                n.标签 = 解析标识符();
            }
            解析分号();
            返回 完成节点(n);
        }

        函数 解析返回语句(): 返回语句_ {
            常量 n = <返回语句_>创建节点(语法_.返回语句_);
            解析预期(语法_.返回_);
            n.表达式 = 解析逗号列表(解析语义_.返回语句列表_, 解析表达式);
            解析分号();
            返回 完成节点(n);
        }

        函数 解析若是子句(): 若是子句_ {
            常量 n = <若是子句_>创建节点(语法_.若是子句_);
            解析预期(语法_.若是_);
            n.表达式 = 解析表达式();
            解析预期(语法_.冒号_);
            n.语句组 = 解析列表(解析语义_.假如若是语句_, 解析语句);
            返回 完成节点(n);
        }

        函数 解析默认子句(): 默认子句_ {
            常量 n = <默认子句_>创建节点(语法_.默认子句_);
            解析预期(语法_.默认_);
            解析预期(语法_.冒号_);
            n.语句组 = 解析列表(解析语义_.假如若是语句_, 解析语句);
            返回 完成节点(n);
        }

        函数 解析若是或默认子句(): 若是或默认子句_ {
            返回 令牌() === 语法_.若是_ ? 解析若是子句() : 解析默认子句();
        }

        函数 解析选择语句(): 选择语句_ {
            常量 n = <选择语句_>创建节点(语法_.选择语句_);
            解析预期(语法_.选择_);
            解析预期(语法_.左括号_);
            n.表达式 = 解析表达式();
            解析预期(语法_.右括号_);
            常量 若是块 = <若是块_>创建节点(语法_.若是块_);
            解析预期(语法_.左大括号_);
            若是块.子句组 = 解析列表(解析语义_.假如子句_, 解析若是或默认子句);
            解析预期(语法_.右大括号_);
            n.若是块 = 完成节点(若是块);
            返回 完成节点(n);
        }

        函数 解析假如语句(): 假如语句_ {
            常量 n = <假如语句_>创建节点(语法_.假如语句_);
            解析预期(语法_.假如_);
            解析预期(语法_.左括号_);
            n.表达式 = 解析表达式();
            解析预期(语法_.右括号_);
            常量 若是块 = <若是块_>创建节点(语法_.若是块_);
            解析预期(语法_.左大括号_);
            若是块.子句组 = 解析列表(解析语义_.假如子句_, 解析若是或默认子句);
            解析预期(语法_.右大括号_);
            n.若是块 = 完成节点(若是块);
            返回 完成节点(n);
        }

        函数 解析调试语句(): 语句_ {
            常量 n = <语句_>创建节点(语法_.调试语句_);
            解析预期(语法_.调试_);
            解析分号();
            返回 完成节点(n);
        }

        函数 解析表达式或标签语句(): 表达式语句_ | 标签语句_ {
            常量 n = <表达式语句_ | 标签语句_>创建节点包括JSDoc(语法_.未知_);
            常量 表达式 = 解析表达式();
            如果 (表达式.种类 === 语法_.标识符_ && 解析可选(语法_.冒号_)) {
                n.种类 = 语法_.标签语句_;
                (<标签语句_>n).标签 = <标识符_>表达式;
                (<标签语句_>n).语句 = 解析语句();
            }
            否则 {
                n.种类 = 语法_.表达式语句_;
                (<表达式语句_>n).表达式 = 表达式;
                解析分号();
            }
            返回 完成节点(n);
        }

        函数 下个令牌是在同一行的标识符或关键字() {
            下个令牌();
            返回 令牌是标识符或关键字(令牌()) && !扫描器.具有前导换行符();
        }

        函数 可能是类型名称节点() {
            返回 令牌() === 语法_.标识符_ || 令牌() === 语法_.类型_ || 是内置类型令牌() || 前瞻(是词典类型) || 前瞻(是指针类型) || 是带括号的箭头函数表达式() !== 三态_.为假_
        }

        函数 是内置类型令牌(): 真假 {
            返回 语法_.真假_ <= 令牌() && 令牌() <= 语法_.字节_;
        }

        函数 是指针类型(): 真假 {
            如果 (令牌() !== 语法_.星号_) 返回 为假;
            下个令牌()
            返回 可能是类型名称节点()
        }

        函数 是词典类型(): 真假 {
            如果 (令牌() !== 语法_.左方括号_) 返回 为假;
            下个令牌()
            如果 (!可能是类型名称节点()) 返回 为假;
            下个令牌()
            如果 (令牌() !== 语法_.冒号_) 返回 为假;
            下个令牌()
            如果 (!可能是类型名称节点()) 返回 为假;
            下个令牌()
            返回 令牌() === 语法_.右方括号_;
        }

        函数 是顶级语句开始(): 真假 {
            假如 (令牌()) {
                // 若是 语法_.程序_:
                若是 语法_.导入_:
                若是 语法_.变量_:
                若是 语法_.常量_:
                若是 语法_.预_定义_:
                若是 语法_.预_完成定义_:
                若是 语法_.启动_:
                若是 语法_.初始_:
                若是 语法_.函数_:
                若是 语法_.方法_:
                若是 语法_.接口_:
                若是 语法_.枚举_:
                若是 语法_.类型_:
                若是 语法_.结构_:
                    返回 为真;
                默认:
                    返回 为假;
            }
        }

        函数 是语句开始(): 真假 {
            假如 (令牌()) {
                若是 语法_.分号_:
                若是 语法_.左大括号_:
                若是 语法_.预_定义_:
                若是 语法_.预_完成定义_:
                若是 语法_.如果_:
                若是 语法_.循环_:
                若是 语法_.继续_:
                若是 语法_.跳出_:
                若是 语法_.贯穿_:
                若是 语法_.返回_:
                若是 语法_.假如_:
                若是 语法_.选择_:
                若是 语法_.调试_:
                若是 语法_.变量_:
                若是 语法_.执行_:
                若是 语法_.善后_:
                若是 语法_.删除_:
                    返回 为真;
                默认:
                    返回 是表达式开始();
            }
        }

        函数 解析语句(): 语句_ {
            假如 (令牌()) {
                若是 语法_.预_定义_:
                    返回 解析预处理定义语句();
                若是 语法_.预_完成定义_:
                    返回 解析预处理定义完成语句();
                若是 语法_.分号_:
                    返回 解析空语句();
                若是 语法_.左大括号_:
                    返回 解析块(/*忽略失踪大括号*/ 为假);
                若是 语法_.变量_:
                    返回 解析变量语句(<变量语句_>创建节点包括JSDoc(语法_.变量声明_));
                若是 语法_.标识符_:
                    如果 (前瞻(前方有冒等号令牌)) {
                        返回 解析简洁变量声明();
                    }
                    跳出;
                若是 语法_.如果_:
                    返回 解析如果及另如否则语句();
                若是 语法_.循环_:
                    返回 解析循环语句();
                若是 语法_.继续_:
                    返回 解析跳出或继续语句(语法_.继续语句_);
                若是 语法_.跳出_:
                    返回 解析跳出或继续语句(语法_.跳出语句_);
                若是 语法_.贯穿_:
                    返回 解析贯穿语句();
                若是 语法_.返回_:
                    返回 解析返回语句();
                若是 语法_.假如_:
                    返回 解析假如语句();
                若是 语法_.选择_:
                    返回 解析选择语句();
                若是 语法_.调试_:
                    返回 解析调试语句();
                若是 语法_.删除_:
                    返回 解析删除语句();
                若是 语法_.执行_:
                    返回 解析执行语句();
                若是 语法_.善后_:
                    返回 解析善后语句();
            }
            返回 解析表达式或标签语句();
        }

        函数 解析源码语句(): 导入声明_ | 导入从声明_ | 程序声明_ | 不输出语句_ | 语句_ {
            常量 n = <语句_>创建节点包括JSDoc(语法_.未知_);
            假如 (令牌()) {
                若是 语法_.预_定义_:
                    返回 解析预处理定义语句();
                若是 语法_.预_完成定义_:
                    返回 解析预处理定义完成语句();
                若是 语法_.导入_:
                    返回 解析导入声明或导入从声明(<导入声明_ | 导入从声明_>n)
                默认:
                    返回 解析程序声明(<程序声明_>n)
            }
        }

        函数 解析顶级语句(): 顶级语句_ {
            常量 n = <语句_>创建节点包括JSDoc(语法_.未知_);
            假如 (令牌()) {
                若是 语法_.预_定义_:
                    返回 解析预处理定义语句();
                若是 语法_.预_完成定义_:
                    返回 解析预处理定义完成语句();
                若是 语法_.变量_:
                    返回 解析变量语句(<变量语句_>n);
                若是 语法_.常量_:
                    返回 解析常量语句(<常量语句_ | 常量列表语句_>n);
                若是 语法_.方法_:
                    返回 解析方法声明(<方法声明_>n);
                若是 语法_.函数_:
                    返回 解析函数声明(<函数声明_ | 函数签名_>n) 转为 函数声明_;
                若是 语法_.结构_:
                    返回 解析结构声明(<结构声明_>n);
                若是 语法_.接口_:
                    返回 解析接口声明(<接口声明_>n);
                若是 语法_.枚举_:
                    返回 解析枚举声明(<枚举声明_>n)
                若是 语法_.类型_:
                    返回 解析类型声明或类型别名声明(<类型声明_ | 类型别名声明_>n);
                若是 语法_.初始_:
                    返回 解析启动或初始函数(语法_.初始函数声明_);
                若是 语法_.启动_:
                    返回 解析启动或初始函数(语法_.启动函数声明_);
                默认:
                    常量 失踪的 = 创建失踪节点<语句_>(语法_.失踪声明_, /*报告当前位置*/ 为真, 诊断信息_.应为声明);
                    失踪的.首位 = n.首位;
                    返回 完成节点(失踪的) 转为 失踪语句_;
            }
        }

        函数 前方有冒等号令牌(): 真假 {
            下个令牌();
            判断 ((令牌() === 语法_.标识符_ || 令牌() === 语法_.逗号_ || 令牌() === 语法_.点号_ || 令牌() === 语法_.冒等号_) && !扫描器.具有前导换行符()) {
                如果 (令牌() === 语法_.冒等号_) {
                    返回 为真;
                }
                下个令牌();
            }
            返回 为假;
        }

        函数 解析预处理定义完成语句(): 不输出语句_ {
            常量 n = <不输出语句_>创建节点(语法_.不输出语句_);
            如果 (不跳过预处理尾部 && 解析预期(语法_.预_完成定义_)) {
                不跳过预处理尾部 = 为假;
                返回 完成节点(n);
            }
            解析错误在位置(n.首位, 扫描器.获取开始首位() - n.首位, 诊断信息_.发现应有独立预处理_0_标签, '#完成');
            返回 完成节点(n)
        }

        函数 解析预处理定义语句(): 不输出语句_ {
            常量 n = <不输出语句_>创建节点(语法_.不输出语句_);
            解析预期(语法_.预_定义_);
            变量 预定义变量 = 解析标识符名称();
            如果 (包含(定义的环境变量, 预定义变量.文本)) {
                不跳过预处理尾部 = 为真;
                返回 完成节点(n);
            }
            下个令牌()
            判断 (令牌() !== 语法_.文件结尾令牌_) {
                如果 (解析可选(语法_.预_完成定义_)) {
                    返回 完成节点(n);
                }
                下个令牌()
            }
            解析错误在位置(n.首位, 扫描器.获取开始首位() - n.首位, 诊断信息_.定义的预处理标签_0_缺少_结束_标签, 预定义变量.文本);
            返回 完成节点(n);
        }

        函数 解析导入声明或导入从声明(n?: 导入声明_ | 导入从声明_): 导入声明_ | 导入从声明_ {
            n = n || <导入声明_ | 导入从声明_>创建节点包括JSDoc(语法_.未知_)

            n.种类 = 是导入从声明语句() ? 语法_.导入从声明_ : 语法_.导入声明_;
            解析预期(语法_.导入_);

            常量 有括号 = 解析可选(语法_.左大括号_);
            如果 (是导入从声明语句()) {
                n.种类 = 语法_.导入从声明_;
                n.导入组 = 解析列表(解析语义_.解析导入从语句_, 解析导入从成员);
                解析预期(语法_.右大括号_);
                解析预期(语法_.从_);
                (<导入从声明_>n).模块名 = <文本字面量_>解析字面量族节点(语法_.文本字面量_);
            }
            否则 如果 (有括号) {
                n.种类 = 语法_.导入声明_;
                n.导入组 = 解析列表(解析语义_.解析导入语句_, 解析导入成员);
                解析预期(语法_.右大括号_);
            }
            否则 {
                n.种类 = 语法_.导入声明_;
                n.导入组 = 解析列表(解析语义_.解析单行导入语句_, 解析导入成员);
                解析预期(语法_.分号_);
            }
            返回 完成节点(n);

        }

        函数 解析导入从成员(): 导入从成员_ {
            变量 n = <导入从成员_>创建节点包括JSDoc(语法_.导入从成员_);
            n.名称 = 解析标识符();
            如果 (解析可选(语法_.冒号_)) {
                n.别名 = 解析标识符();
            }
            返回 完成节点(n);
        }

        函数 解析导入成员(): 导入成员_ {
            变量 n = <导入成员_>创建节点包括JSDoc(语法_.导入成员_);
            如果 (令牌() !== 语法_.文本字面量_) {
                n.别名 = 解析标识符();
                解析预期(语法_.冒号_);
            }
            n.模块名 = <文本字面量_>解析字面量族节点(语法_.文本字面量_);
            返回 完成节点(n);
        }

        函数 解析枚举声明(n: 枚举声明_) {
            n.种类 = 语法_.枚举声明_
            解析预期(语法_.枚举_)
            n.名称 = 解析标识符()
            解析预期(语法_.左大括号_)
            n.成员 = 解析列表(解析语义_.枚举声明_, 解析枚举成员)
            解析预期(语法_.右大括号_)
            返回 完成节点(n)
        }

        函数 解析枚举成员(): 枚举成员声明_ {
            常量 n = <枚举成员声明_>创建节点(语法_.枚举成员声明_)
            n.名称 = 解析标识符()
            如果 (解析可选(语法_.等号_)) {
                n.初始化 = 解析表达式()
            }
            解析分号()
            返回 完成节点(n)
        }

        函数 解析常量语句(n: 常量语句_ | 常量列表语句_): 常量语句_ | 常量列表语句_ {
            解析预期(语法_.常量_);
            如果 (解析可选(语法_.左大括号_)) {
                n.种类 = 语法_.常量列表语句_;
                (<常量列表语句_>n).声明组 = 解析列表(解析语义_.常量列表语句_, 解析常量列表语句元素);
                解析预期(语法_.右大括号_)
                返回 完成节点(n);
            }
            n.种类 = 语法_.常量语句_;
            (<常量语句_>n).声明组 = 解析逗号列表(解析语义_.变量声明_, 解析常量声明元素);
            解析预期(语法_.等号_);
            (<常量语句_>n).初始化组 = 解析逗号列表(解析语义_.初始化组_, 解析表达式);
            返回 完成节点(n);
        }

        函数 解析常量列表语句元素() {
            常量 n = <常量列表元素_>创建节点包括JSDoc(语法_.常量列表元素_);
            n.名称 = 解析标识符名称();
            如果 (解析可选(语法_.等号_)) {
                n.初始化 = 解析表达式();
            }
            解析分号()
            返回 完成节点(n);
        }

        函数 解析常量声明元素(): 常量声明_ {
            常量 n = <常量声明_>创建节点包括JSDoc(语法_.常量声明_);
            n.名称 = 解析标识符名称();
            返回 完成节点(n);
        }

        函数 解析简洁变量声明(非循环体内 = 为真): 简洁变量语句_ {
            常量 n = <简洁变量语句_>创建节点包括JSDoc(语法_.简洁变量语句_);
            n.声明组 = 解析逗号列表(解析语义_.变量声明_, 解析变量声明元素);
            如果 (!非循环体内) {
                解析可选(语法_.冒等号_);
                解析可选(语法_.属于_);
            }
            否则 {
                解析预期(语法_.冒等号_);
            }
            n.初始化组 = 解析逗号列表(非循环体内 ? 解析语义_.初始化组_ : 解析语义_.循环体内初始化_, 解析表达式);
            返回 完成节点(n);
        }

        函数 解析变量语句(n: 变量语句_): 变量语句_ {
            n.种类 = 语法_.变量语句_;
            解析预期(语法_.变量_);
            n.声明组 = 解析逗号列表(解析语义_.变量声明_, 解析变量声明元素);
            如果 (解析可选(语法_.等号_)) {
                n.初始化组 = 解析逗号列表(解析语义_.初始化组_, 解析表达式);
            }
            返回 完成节点(n);
        }

        函数 解析变量声明元素(): 变量声明_ {
            常量 n = <变量声明_>创建节点包括JSDoc(语法_.变量声明_);
            n.名称 = 解析标识符();
            n.类型 = 解析参数类型();
            返回 完成节点(n);
        }

        函数 解析循环属于变量声明(): 变量声明_ {
            常量 n = <变量声明_>创建节点包括JSDoc(语法_.变量声明_);
            n.名称 = 解析标识符();
            返回 完成节点(n);
        }

        函数 是导入从声明语句(): 真假 {
            返回 前瞻(前方有来自关键字);
        }

        函数 前方有来自关键字(): 真假 {
            判断 (令牌() !== 语法_.文件结尾令牌_) {
                如果 (令牌() === 语法_.右大括号_) {
                    跳出;
                }
                下个令牌();
            }
            下个令牌();
            返回 解析预期(语法_.从_);
        }

        函数 解析善后语句(): 善后语句_ {
            常量 n = <善后语句_>创建节点(语法_.善后语句_);
            解析预期(语法_.善后_);
            n.表达式 = 解析表达式();
            返回 完成节点(n);
        }

        函数 解析执行语句(): 执行语句_ {
            常量 n = <执行语句_>创建节点(语法_.执行语句_);
            解析预期(语法_.执行_);
            n.表达式 = 解析表达式();
            返回 完成节点(n);
        }

        函数 解析删除语句(): 删除语句_ {
            常量 n = <删除语句_>创建节点(语法_.删除语句_);
            解析预期(语法_.删除_);
            n.表达式 = 解析表达式() 转为 元素访问表达式_;
            返回 完成节点(n);
        }

        函数 解析启动或初始函数(语法: 语法_.启动函数声明_ | 语法_.初始函数声明_): 启动函数声明_ | 初始函数声明_ {
            变量 n = <启动函数声明_ | 初始函数声明_>创建节点包括JSDoc(语法);
            n.名称 = 解析标识符名称();
            解析预期(语法_.左括号_);
            解析预期(语法_.右括号_);
            n.主体 = 解析块(为假, 诊断信息_.应为_或);
            返回 完成节点(n);
        }

        函数 解析函数声明(n: 函数声明_ | 函数签名族_): 函数声明_ | 函数签名族_ {
            n.种类 = 语法_.函数声明_;
            解析预期(语法_.函数_);
            如果 (!!(节点语义标志 & 节点标志_.环境_)) {
                如果 (令牌() === 语法_.创建_) {
                    n.种类 = 语法_.创建函数签名_;
                    n.名称 = 解析标识符名称();
                    (<创建函数签名_>n).类型参数 = parseTypeParameters()
                    解析预期(语法_.左括号_);
                    n.参数 = 解析逗号列表(解析语义_.参数声明_, 解析参数元素);
                    解析预期(语法_.右括号_);
                    解析预期(语法_.冒号_);
                    n.类型 = 解析返回值声明();
                    返回 完成节点(n);
                }
            }
            n.名称 = 解析标识符();
            n.类型参数 = parseTypeParameters()
            解析预期(语法_.左括号_);
            n.参数 = 解析逗号列表(解析语义_.参数声明_, 解析参数元素);
            解析预期(语法_.右括号_);
            如果 (解析可选(语法_.冒号_)) {
                n.类型 = 解析返回值声明();
            }
            如果 (是函数声明(n)) {
                n.主体 = 解析函数块(n)!;
            }
            返回 完成节点(n);
        }

        函数 解析函数块(n: 函数声明_ | 函数签名_) {
            如果 (!!(节点语义标志 & 节点标志_.环境_)) {
                n.种类 = 语法_.函数签名_
                解析分号()
                返回 未定;
            }
            返回 解析块(为假, 诊断信息_.应为_或);
        }

        函数 解析返回值声明(): 返回值声明属性组_ {
            变量 有括号 = 是带括号的箭头函数表达式() ? 为假 : 解析可选(语法_.左括号_);
            常量 列表 = [];
            常量 列表首位 = 获取节点首位();
            判断 (令牌() !== 语法_.文件结尾令牌_) {
                如果 (前瞻(结束之前无冒号)) {
                    变量 tns = 解析逗号列表(解析语义_.返回值声明列表_, 解析类型);
                    如果 (有括号) {
                        解析预期(语法_.右括号_);
                    }
                    常量 返回值 = <返回值声明属性组_>创建节点(语法_.返回值声明属性组_)
                    返回值.首位 = tns.首位
                    返回值.尾位 = tns.尾位
                    返回值.具有匿名成员 = 为真;
                    返回值.声明组 = tns
                    返回 返回值;
                }
                否则 {
                    变量 ns = 解析逗号列表(解析语义_.返回值声明列表_, 解析属性列表成员声明);
                    列表.压入(...ns);
                }
                如果 (是返回值终结者()) 跳出;
            }
            常量 n = 创建节点数组(列表, 列表首位);
            如果 (有括号) {
                解析预期(语法_.右括号_);
            }
            常量 返回值 = <返回值声明属性组_>创建节点(语法_.返回值声明属性组_)
            返回值.首位 = n.首位
            返回值.尾位 = n.尾位
            返回值.声明组 = n
            返回 返回值;
        }

        函数 解析方法声明(n: 方法声明_): 方法声明_ {
            n.种类 = 语法_.方法声明_;
            解析预期(语法_.方法_);
            n.接受者 = 解析方法接收者();
            解析预期(语法_.点号_);
            n.名称 = 解析标识符();
            n.类型参数 = parseTypeParameters()
            解析预期(语法_.左括号_);
            n.参数 = 解析逗号列表(解析语义_.参数声明_, 解析参数元素);
            解析预期(语法_.右括号_);
            如果 (解析可选(语法_.冒号_)) {
                n.类型 = 解析返回值声明();
            }
            n.主体 = 解析块(为假, 诊断信息_.应为_或);
            返回 完成节点(n);
        }

        函数 解析结构声明(n: 结构声明_): 结构声明_ {
            n.种类 = 语法_.结构声明_;
            解析预期(语法_.结构_);
            n.名称 = 解析标识符();
            n.类型参数 = parseTypeParameters()
            解析预期(语法_.左大括号_);
            n.成员 = 解析结构成员声明();
            解析预期(语法_.右大括号_);

            返回 完成节点(n);
        }

        /**
         * 
         * 结构 A {
         *     B;             // 匿名结构成员
         *     i: 整数;       // 独立的属性
         *     s, ss : 文本   // 列表声明
         *     arr: 整数[4];  // 可选分号
         * }
         * 
         */
        函数 解析结构成员声明(): 节点数组_<结构声明属性组_> {
            返回 解析列表(解析语义_.结构声明属性组_, 解析结构声明属性组);
        }

        函数 解析结构声明属性组() {
            常量 n = <结构声明属性组_>创建节点包括JSDoc(语法_.结构声明属性组_)
            常量 列表 = [];
            常量 列表首位 = 获取节点首位();
            如果 (前瞻(结束之前无冒号)) {
                变量 数组 = 解析逗号列表(解析语义_.结构成员声明_, 解析匿名属性列表成员声明, 为真);
                n.具有匿名成员 = 为真;
                列表.压入(...数组);
            }
            否则 {
                变量 数组 = 解析逗号列表(解析语义_.结构成员声明_, 解析属性列表成员声明, 为真);
                列表.压入(...数组);
            }
            如果 (可以解析分号()) {
                解析分号()
            }
            n.声明组 = 创建节点数组(列表, 列表首位);
            返回 完成节点(n);
        }

        函数 结束之前无冒号() {
            标签1: 判断 (令牌() !== 语法_.右大括号_ && 令牌() !== 语法_.右括号_ && 令牌() !== 语法_.文件结尾令牌_) {
                如果 ((令牌() === 语法_.左方括号_)) {
                    判断 (令牌() !== 语法_.右方括号_ && 令牌() !== 语法_.右大括号_ && 令牌() !== 语法_.文件结尾令牌_) {
                        如果 (令牌() === 语法_.冒号_) {
                            下个令牌()
                            继续 标签1
                        }
                        下个令牌()
                    }
                }
                如果 (令牌() === 语法_.等右尖号_) {
                    下个令牌()
                    如果 (令牌() === 语法_.冒号_) {
                        下个令牌()
                        继续
                    }
                    继续
                }
                如果 (令牌() === 语法_.冒号_) {
                    返回 为假;
                }
                如果 (令牌() === 语法_.分号_) {
                    返回 为真;
                }
                下个令牌()
                如果 (扫描器.具有前导换行符()) {
                    返回 为真;
                }
            }
            返回 为真;
        }

        函数 跳过指针类型(tn: 类型节点_) {
            判断 (是指针类型节点(tn)) {
                tn = tn.基础类型
            }
            返回 tn
        }

        函数 转换类型节点为匿名属性声明名称节点(tn: 类型节点_) {
            如果 (!(tn.标志 & 节点标志_.这个节点有错误_)) {
                tn = 是指针类型节点(tn) ? 跳过指针类型(tn) : tn
                变量 n = <标识符_>ts.创建节点(语法_.标识符_, tn.首位, tn.尾位);
                常量 名称 = 获取命名的类型节点名称(tn);
                如果 (!名称) {
                    n.标志 |= 节点标志_.这个节点有错误_;
                    n = 创建失踪节点(语法_.标识符_, 为真, 诊断信息_.匿名属性只能是命名的类型节点)
                    返回 n
                }
                n.文本 = 名称
                返回 n;
            }
        }

        函数 解析匿名属性列表成员声明(): 属性声明_ {
            变量 n = <属性声明_>创建节点包括JSDoc(语法_.属性声明_);
            n.类型 = 解析类型();
            n.是匿名成员 = 为真;
            n.名称 = 转换类型节点为匿名属性声明名称节点(n.类型)
            返回 完成节点(n);
        }

        函数 解析属性列表成员声明() {
            变量 n = <属性声明_>创建节点包括JSDoc(语法_.属性声明_);
            n.名称 = 解析标识符();
            如果 (解析可选(语法_.冒号_)) {
                n.类型 = 解析类型();
            }
            返回 完成节点(n);
        }

        函数 解析接口声明(n: 接口声明_): 接口声明_ {
            n.种类 = 语法_.接口声明_;
            解析预期(语法_.接口_);
            n.名称 = 解析标识符();
            n.类型参数 = parseTypeParameters()
            n.成员 = 解析接口成员声明();
            返回 完成节点(n);
        }

        函数 当前类型声明是类型别名声明() {
            返回 前瞻(前方换行前具有逗号及冒等号);
        }

        常量 枚举 类型类别_ {
            无_ = 0,
            类型_ = 1 << 1,
            类型别名_ = 1 << 2,
        }

        函数 前方换行前具有逗号及冒等号() {
            下个令牌()
            变量 类型语法种类 = 类型类别_.无_;
            判断 (令牌() !== 语法_.文件结尾令牌_) {
                如果 (令牌() === 语法_.冒等号_) {
                    类型语法种类 |= 类型类别_.类型_
                    返回 类型语法种类
                }
                如果 (令牌() === 语法_.等号_) {
                    返回 类型语法种类 |= 类型类别_.类型别名_
                }
                如果 (扫描器.具有前导换行符()) {
                    返回 类型类别_.无_;
                }
                下个令牌()
            }
            返回 类型类别_.无_;
        }

        函数 解析类型声明或类型别名声明(n: 类型声明_ | 类型别名声明_ ): 类型声明_ | 类型别名声明_ {
            解析预期(语法_.类型_);
            常量 类型声明类别 = 当前类型声明是类型别名声明();
            如果 (类型声明类别 === 类型类别_.类型_) {
                n.种类 = 语法_.类型声明_;
                (<类型声明_>n).名称 = 解析标识符();
                n.类型参数 = parseTypeParameters()
                如果 (解析可选(语法_.冒等号_)) {
                    n.种类 = 语法_.类型声明_;
                }
                (<类型声明_>n).类型 = 解析类型();
            }
            否则 {
                n.种类 = 语法_.类型别名声明_;
                (<类型别名声明_>n).名称 = 解析标识符();
                n.类型参数 = parseTypeParameters()
                如果 (解析可选(语法_.等号_)) {
                    n.种类 = 语法_.类型别名声明_;
                }
                (<类型别名声明_>n).类型 = 解析类型();
            }

            解析分号();
            返回 完成节点(n);
        }

        函数 解析程序声明(n: 程序声明_): 程序声明_ {
            n.种类 = 语法_.程序声明_;
            如果 (解析可选(语法_.程序_)) {
                如果 (令牌() === 语法_.启动_) {
                    n.是启动声明 = 为真;
                    n.名称 = 解析标识符名称();
                }
                否则 {
                    n.名称 = 解析标识符();
                }
                解析分号();
            }
            否则 {
                n.名称 = <标识符_>创建节点(语法_.标识符_, -1);
                n.名称.首位 = -1
                变量 路径片段 = 正规化路径和片段(获取目录路径(源文件.文件名));
                变量 目录名 = 最后或未定义(路径片段.片段)!
                n.名称.文本 = 目录名 === '源码' ? '启动' : 目录名;
                如果 (n.名称.文本 === '启动') n.是启动声明 = 为真;
                n.名称.尾位 = -1
                n.名称.标志 |= 节点标志_.合成的_
            }
            n.语句组 = 解析列表(解析语义_.源码元素_, 解析顶级语句);
            返回 完成节点(n);
        }

        导出 名域 JSDoc解析_ {

            导出 函数 解析独立JSDoc注释(内容: 文字, 开始: 数字 | 未定, 长度: 数字 | 未定): { jsDoc: JSDoc_, diagnostics: 诊断_[] } | 未定 {
                初始化状态(内容, /*_语法光标:*/ 未定!, 脚本种类_.K);
                源文件 = <源文件_>{ 语言版本: 语言版本_.标准_, 文本: 内容 };
                常量 jsDoc = 解析JSDoc注释平台(开始, 长度);
                常量 diagnostics = 解析诊断信息;
                清除状态();

                返回 jsDoc ? { jsDoc, diagnostics } : 未定;
            }

            导出 函数 解析JSDoc注释(父节点: 有JSDoc_, 开始: 数字, 长度: 数字): JSDoc_ {
                常量 储存令牌 = 当前令牌;
                常量 储存解析诊断信息长度 = 解析诊断信息.长度;
                常量 储存解析错误下个节点完成之前 = 解析错误下个节点完成之前;

                常量 注释 = 解析JSDoc注释平台(开始, 长度);
                如果 (注释) {
                    注释.父节点 = 父节点;
                }

                如果 (节点语义标志 & 节点标志_.Klang文件_) {
                    如果 (!源文件.jsDoc诊断信息) {
                        源文件.jsDoc诊断信息 = [];
                    }
                    源文件.jsDoc诊断信息.压入(...解析诊断信息);
                }
                当前令牌 = 储存令牌;
                解析诊断信息.长度 = 储存解析诊断信息长度;
                解析错误下个节点完成之前 = 储存解析错误下个节点完成之前;

                返回 注释;
            }

            常量 枚举 JSDoc状态_ {
                行首_,
                星号_,
                保存注释_,
            }

            导出 函数 解析JSDoc注释平台(开始 = 0, 长度: 数字 | 未定): JSDoc_ {
                常量 内容 = 源文本;
                开始 = 开始 || 0;
                常量 尾位 = 长度 === 未定 ? 内容.长度 : 开始 + 长度;
                长度 = 尾位 - 开始;

                调试_.断言(开始 >= 0);
                调试_.断言(开始 <= 尾位);
                调试_.断言(尾位 <= 内容.长度);

                变量 标签组: JSDoc标签_[];
                变量 标签首位: 数字;
                变量 标签尾位: 数字;
                常量 注释组: 文字[] = [];
                变量 结果!: JSDoc_;

                如果 (!是JsDoc开始(内容, 开始)) {
                    返回 结果;
                }

                扫描器.扫描范围(开始 + 3, 长度 - 5, () => {
                    变量 状态 = JSDoc状态_.星号_;
                    变量 外边框: 数字 | 未定;
                    变量 缩进 = 开始 - 数学_.max(内容.最后索引位于('\n', 开始), 0) + 4;
                    函数 压入注释(文本: 文字) {
                        如果 (!外边框) {
                            外边框 = 缩进;
                        }
                        注释组.压入(文本);
                        缩进 += 文本.长度;
                    }

                    变量 t = 下个JSDoc令牌();
                    判断 (t === 语法_.空白杂项_) {
                        t = 下个JSDoc令牌();
                    }
                    如果 (t === 语法_.新行杂项_) {
                        状态 = JSDoc状态_.行首_;
                        缩进 = 0;
                        t = 下个JSDoc令牌();
                    }
                    连续: 判断 (为真) {
                        假如 (t) {
                            若是 语法_.艾特号_:
                                如果 (状态 === JSDoc状态_.行首_ || 状态 === JSDoc状态_.星号_) {
                                    删除尾随新行(注释组);
                                    解析JSDoc标签(缩进);
                                    状态 = JSDoc状态_.行首_;
                                    外边框 = 未定;
                                    缩进++;
                                }
                                否则 {
                                    压入注释(扫描器.获取令牌文本());
                                }
                                跳出;
                            若是 语法_.新行杂项_:
                                注释组.压入(扫描器.获取令牌文本());
                                状态 = JSDoc状态_.行首_;
                                缩进 = 0;
                                跳出;
                            若是 语法_.星号_:
                                常量 星号_ = 扫描器.获取令牌文本();
                                如果 (状态 === JSDoc状态_.星号_ || 状态 === JSDoc状态_.保存注释_) {
                                    状态 = JSDoc状态_.保存注释_;
                                    压入注释(星号_);
                                }
                                否则 {
                                    状态 = JSDoc状态_.星号_;
                                    缩进 += 星号_.长度;
                                }
                                跳出;
                            若是 语法_.标识符_:
                                压入注释(扫描器.获取令牌文本());
                                状态 = JSDoc状态_.保存注释_;
                                跳出;
                            若是 语法_.空白杂项_:
                                常量 空白范围 = 扫描器.获取令牌文本();
                                如果 (状态 === JSDoc状态_.保存注释_) {
                                    注释组.压入(空白范围);
                                }
                                否则 如果 (外边框 !== 未定 && 缩进 + 空白范围.长度 > 外边框) {
                                    注释组.压入(空白范围.分切(外边框 - 缩进 - 1));
                                }
                                缩进 += 空白范围.长度;
                                跳出;
                            若是 语法_.文件结尾令牌_:
                                跳出 连续;
                            默认:
                                状态 = JSDoc状态_.保存注释_;
                                压入注释(扫描器.获取令牌文本());
                                跳出;
                        }
                        t = 下个JSDoc令牌();
                    }
                    删除前导新行(注释组);
                    删除尾随新行(注释组);
                    结果 = 创建JSDoc注释();

                });

                返回 结果;

                函数 删除前导新行(注释组: 文字[]) {
                    判断 (注释组.长度 && (注释组[0] === '\n' || 注释组[0] === '\r')) {
                        注释组.推出();
                    }
                }

                函数 删除尾随新行(注释组: 文字[]) {
                    判断 (注释组.长度 && (注释组[注释组.长度 - 1] === '\n' || 注释组[注释组.长度 - 1] === '\r')) {
                        注释组.弹出();
                    }
                }

                函数 是JsDoc开始(内容: 文字, 开始: 数字) {
                    返回 内容.字符代码在(开始) === 字符_.斜杠号_ &&
                        内容.字符代码在(开始 + 1) === 字符_.星号_ &&
                        内容.字符代码在(开始 + 2) === 字符_.星号_ &&
                        内容.字符代码在(开始 + 3) !== 字符_.星号_;
                }

                函数 创建JSDoc注释(): JSDoc_ {
                    常量 结果 = <JSDoc_>创建节点(语法_.JsDoc注释_, 开始);
                    结果.标签组 = 标签组 && 创建节点数组(标签组, 标签首位, 标签尾位);
                    结果.注释 = 注释组.长度 ? 注释组.连结('') : 未定;
                    返回 完成节点(结果, 尾位);
                }

                函数 通过空白(): 无值 {
                    判断 (令牌() === 语法_.空白杂项_ || 令牌() === 语法_.新行杂项_) {
                        下个JSDoc令牌();
                    }
                }

                函数 解析JSDoc标签(缩进: 数字) {
                    调试_.断言(令牌() === 语法_.艾特号_);
                    常量 艾特 = <艾特号_>创建节点(语法_.艾特号_, 扫描器.获取令牌首位());
                    艾特.尾位 = 扫描器.获取文本首位();
                    下个JSDoc令牌();

                    常量 标签名 = 解析JSDoc标识符名称();
                    通过空白();
                    如果 (!标签名) {
                        返回;
                    }

                    变量 标签!: JSDoc标签_;
                    如果 (标签名 && 标签名.文本) {
                        标签 = 解析未知标签(艾特, 标签名);
                    }
                    否则 {
                        标签 = 解析未知标签(艾特, 标签名);
                    }

                    如果 (!标签!) {
                        返回;
                    }
                    标签.注释 = 解析标签注释(缩进 + 标签.尾位 - 标签.首位);
                    添加标签(标签);
                }

                函数 解析标签注释(缩进: 数字): 文字 | 未定 {
                    常量 注释组: 文字[] = [];
                    变量 状态 = JSDoc状态_.行首_;
                    变量 外边框: 数字 | 未定;
                    函数 压入注释(文本: 文字) {
                        如果 (!外边框) {
                            外边框 = 缩进;
                        }
                        注释组.压入(文本);
                        缩进 += 文本.长度;
                    }
                    变量 tok = 令牌() 转为 JsDoc语法_;
                    连续: 判断 (为真) {
                        假如 (tok) {
                            若是 语法_.新行杂项_:
                                如果 (状态 >= JSDoc状态_.星号_) {
                                    状态 = JSDoc状态_.行首_;
                                    注释组.压入(扫描器.获取令牌文本());
                                }
                                缩进 = 0;
                                跳出;
                            若是 语法_.艾特号_:
                                扫描器.设置文本首位(扫描器.获取文本首位() - 1);
                            // 贯穿
                            若是 语法_.文件结尾令牌_:
                                跳出 连续;
                            若是 语法_.空白杂项_:
                                如果 (状态 === JSDoc状态_.保存注释_) {
                                    压入注释(扫描器.获取令牌文本());
                                }
                                否则 {
                                    常量 空白范围 = 扫描器.获取令牌文本();
                                    如果 (外边框 !== 未定 && 缩进 + 空白范围.长度 > 外边框) {
                                        注释组.压入(空白范围.分切(外边框 - 缩进 - 1));
                                    }
                                    缩进 += 空白范围.长度;
                                }
                                跳出;
                            若是 语法_.星号_:
                                如果 (状态 === JSDoc状态_.行首_) {
                                    状态 = JSDoc状态_.星号_;
                                    缩进 += 1;
                                    跳出;
                                }
                            // 贯穿
                            默认:
                                状态 = JSDoc状态_.保存注释_;
                                压入注释(扫描器.获取令牌文本());
                                跳出;
                        }
                        tok = 下个JSDoc令牌();
                    }

                    删除前导新行(注释组);
                    删除尾随新行(注释组);
                    返回 注释组.长度 === 0 ? 未定 : 注释组.连结('');
                }

                函数 解析未知标签(艾特: 艾特号_, 标签名: 标识符_) {
                    常量 结果 = <JSDoc标签_>创建节点(语法_.JSDoc标签_, 艾特.首位);
                    结果.艾特 = 艾特;
                    结果.标签名 = 标签名;
                    返回 完成节点(结果);
                }

                函数 添加标签(标签: JSDoc标签_): 无值 {
                    如果 (!标签组) {
                        标签组 = [标签];
                        标签首位 = 标签.首位;
                    }
                    否则 {
                        标签组.压入(标签);
                    }
                    标签尾位 = 标签.尾位;
                }

                函数 下个JSDoc令牌(): JsDoc语法_ {
                    返回 当前令牌 = 扫描器.扫描JSDoc令牌();
                }

                函数 解析JSDoc标识符名称(): 标识符_ | 未定;
                函数 解析JSDoc标识符名称(如果缺少创建: 为真): 标识符_;
                函数 解析JSDoc标识符名称(如果缺少创建 = 为假): 标识符_ | 未定 {
                    如果 (!令牌是标识符或关键字(令牌())) {
                        如果 (如果缺少创建) {
                            返回 创建失踪节点<标识符_>(语法_.标识符_, /*报告当前位置*/ 为真, 诊断信息_.应为标识符);
                        }
                        否则 {
                            解析错误在当前令牌(诊断信息_.应为标识符);
                            返回 未定;
                        }
                    }

                    常量 首位 = 扫描器.获取令牌首位();
                    常量 尾位 = 扫描器.获取文本首位();
                    常量 结果 = <标识符_>创建节点(语法_.标识符_, 首位);
                    结果.文本 = 内容.子文字(首位, 尾位);
                    完成节点(结果, 尾位);

                    下个JSDoc令牌();
                    返回 结果;
                }
            }
        }
    }

    名域 增量解析器_ {
        导出 函数 更新源文件(源文件: 源文件_, 新文本: 文字, 文本改变范围: 文本改变范围_, 选项: 编译选项_, 侵略性检查: 真假): 源文件_ {
            侵略性检查 = 侵略性检查 || 调试_.应该断言(断言等级_.积极_);

            检查改变范围(源文件, 新文本, 文本改变范围, 侵略性检查);
            如果 (文本改变范围是未变(文本改变范围)) {
                返回 源文件;
            }

            如果 (源文件.语句组.长度 === 0) {
                返回 解析_.解析源文件(源文件.文件名, 新文本, 源文件.脚本目标, /*语法光标*/ 未定, 选项,/*设置父节点*/ 为真, 源文件.脚本种类);
            }
            常量 增量源文件 = <增量节点_><节点_>源文件;
            调试_.断言(!增量源文件.已增量分析);
            增量源文件.已增量分析 = 为真;

            常量 旧文本 = 源文件.文本;
            常量 语法光标 = 创建语法光标(源文件);
            常量 改变范围 = 扩展到受影响范围(源文件, 文本改变范围);
            检查改变范围(源文件, 新文本, 改变范围, 侵略性检查);
            调试_.断言(改变范围.跨度.开始 <= 文本改变范围.跨度.开始);
            调试_.断言(文本跨度首位(改变范围.跨度) === 文本跨度首位(文本改变范围.跨度));
            调试_.断言(文本跨度首位(文本改变范围新跨度(改变范围)) === 文本跨度首位(文本改变范围新跨度(文本改变范围)));
            常量 增量量 = 文本改变范围新跨度(改变范围).长度 - 改变范围.跨度.长度;
            更新令牌位置和制作元素(增量源文件,
                改变范围.跨度.开始, 文本跨度首位(改变范围.跨度), 文本跨度首位(文本改变范围新跨度(改变范围)), 增量量, 旧文本, 新文本, 侵略性检查);
            常量 结果 = 解析_.解析源文件(源文件.文件名, 新文本, 源文件.脚本目标, 语法光标, 选项, /*设置父节点*/ 为真, 源文件.脚本种类);

            返回 结果;
        }

        函数 移动元素完全过去改变范围(元素: 增量元素, 是数组: 真假, 增量量: 数字, 旧文本: 文字, 新文本: 文字, 侵略性检查: 真假) {
            如果 (是数组) {
                访问数组(<增量节点数组_>元素);
            }
            否则 {
                访问节点(<增量节点_>元素);
            }
            返回;

            函数 访问节点(n: 增量节点_) {
                变量 文本 = '';
                如果 (侵略性检查 && 应检查节点_(n)) {
                    文本 = 旧文本.子文字(n.首位, n.尾位);
                }
                如果 (n._子节点) {
                    n._子节点 = 未定!;
                }

                n.首位 += 增量量;
                n.尾位 += 增量量;

                如果 (侵略性检查 && 应检查节点_(n)) {
                    调试_.断言(文本 === 新文本.子文字(n.首位, n.尾位));
                }

                遍历子节点(n, 访问节点, 访问数组);
                如果 (具有JSDoc节点组(n)) {
                    循环 (常量 jsDoc注释 属于 n.jsDoc!) {
                        遍历子节点(jsDoc注释, 访问节点, 访问数组);
                    }
                }
                检查节点位置(n, 侵略性检查);
            }

            函数 访问数组(数组: 增量节点数组_) {
                数组._子节点 = 未定!;
                数组.首位 += 增量量;
                数组.尾位 += 增量量;

                循环 (常量 n 属于 数组) {
                    访问节点(n);
                }
            }
        }

        函数 应检查节点_(n: 节点_) {
            假如 (n.种类) {
                若是 语法_.文本字面量_:
                若是 语法_.数字字面量_:
                若是 语法_.标识符_:
                    返回 为真;
            }

            返回 为假;
        }

        函数 调整相交元素(元素: 增量元素, 改变开始: 数字, 改变范围旧尾位: 数字, 改变范围新尾位: 数字, 增量量: 数字) {
            调试_.断言(元素.尾位 >= 改变开始, '调整完全在更改范围之前的元素');
            调试_.断言(元素.首位 <= 改变范围旧尾位, '调整完全在更改范围之后的元素');
            调试_.断言(元素.首位 <= 元素.尾位);
            元素.首位 = 数学_.min(元素.首位, 改变范围新尾位);
            如果 (元素.尾位 >= 改变范围旧尾位) {
                元素.尾位 += 增量量;
            }
            否则 {
                元素.尾位 = 数学_.min(元素.尾位, 改变范围新尾位);
            }

            调试_.断言(元素.首位 <= 元素.尾位);
            如果 (元素.父节点) {
                调试_.断言(元素.首位 >= 元素.父节点.首位);
                调试_.断言(元素.尾位 <= 元素.父节点.尾位);
            }
        }

        函数 检查节点位置(n: 节点_, 侵略性检查: 真假) {
            如果 (侵略性检查) {
                变量 首位 = n.首位;
                遍历子节点(n, nc => {
                    调试_.断言(nc.首位 >= 首位);
                    首位 = nc.尾位;
                });
                调试_.断言(首位 <= n.尾位);
            }
        }

        函数 更新令牌位置和制作元素(
            源文件: 增量节点_,
            改变开始: 数字,
            改变范围旧尾位: 数字,
            改变范围新尾位: 数字,
            增量量: 数字,
            旧文本: 文字,
            新文本: 文字,
            侵略性检查: 真假): 无值 {

            访问节点(源文件);
            返回;

            函数 访问节点(nc: 增量节点_) {
                调试_.断言(nc.首位 <= nc.尾位);
                如果 (nc.首位 > 改变范围旧尾位) {
                    移动元素完全过去改变范围(nc, /*isArray*/ 为假, 增量量, 旧文本, 新文本, 侵略性检查);
                    返回;
                }

                常量 全部尾位 = nc.尾位;
                如果 (全部尾位 >= 改变开始) {
                    nc.相交改变 = 为真;
                    nc._子节点 = 未定!;
                    调整相交元素(nc, 改变开始, 改变范围旧尾位, 改变范围新尾位, 增量量);
                    遍历子节点(nc, 访问节点, 访问数组);

                    检查节点位置(nc, 侵略性检查);
                    返回;
                }
                调试_.断言(全部尾位 < 改变开始);
            }

            函数 访问数组(数组: 增量节点数组_) {
                调试_.断言(数组.首位 <= 数组.尾位);
                如果 (数组.首位 > 改变范围旧尾位) {
                    移动元素完全过去改变范围(数组, /*isArray*/ 为真, 增量量, 旧文本, 新文本, 侵略性检查);
                    返回;
                }
                常量 全尾位 = 数组.尾位;
                如果 (全尾位 >= 改变开始) {
                    数组.相交改变 = 为真;
                    数组._子节点 = 未定!;
                    调整相交元素(数组, 改变开始, 改变范围旧尾位, 改变范围新尾位, 增量量);
                    循环 (常量 n 属于 数组) {
                        访问节点(n);
                    }
                    返回;
                }
                调试_.断言(全尾位 < 改变开始);
            }
        }

        函数 扩展到受影响范围(源文件: 源文件_, 改变范围: 文本改变范围_): 文本改变范围_ {
            常量 最大展望 = 1;

            变量 开始 = 改变范围.跨度.开始;
            循环 (变量 i = 0; 开始 > 0 && i <= 最大展望; i++) {
                常量 最近节点 = 查找从位置之前或位置处开始最近的节点(源文件, 开始);
                调试_.断言(最近节点.首位 <= 开始);
                常量 位置 = 最近节点.首位;

                开始 = 数学_.max(0, 位置 - 1);
            }

            常量 最终跨度 = 从边界创建文本范围(开始, 文本跨度首位(改变范围.跨度));
            常量 最终长度 = 改变范围.新长度 + (改变范围.跨度.开始 - 开始);

            返回 创建文本改变范围(最终跨度, 最终长度);
        }

        函数 查找从位置之前或位置处开始最近的节点(源文件: 源文件_, 位置: 数字): 节点_ {
            变量 最佳结果: 节点_ = 源文件;
            变量 位置之前的最后一个节点!: 节点_;

            遍历子节点(源文件, 访问);

            如果 (位置之前的最后一个节点) {
                常量 位置之前最后一个完整节点的子节点 = 获取最后子(位置之前的最后一个节点);
                如果 (位置之前最后一个完整节点的子节点.首位 > 最佳结果.首位) {
                    最佳结果 = 位置之前最后一个完整节点的子节点;
                }
            }

            返回 最佳结果;

            函数 获取最后子(n: 节点_): 节点_ {
                判断 (为真) {
                    常量 最后子 = 获取最后子平台(n);
                    如果 (最后子) {
                        n = 最后子;
                    }
                    否则 {
                        返回 n;
                    }
                }
            }

            函数 获取最后子平台(n: 节点_): 节点_ | 未定 {
                变量 最后的!: 节点_;
                遍历子节点(n, nc => {
                    如果 (节点是存在的(nc)) {
                        最后的 = nc;
                    }
                });
                返回 最后的;
            }

            函数 访问(nc: 节点_) {
                如果 (节点是失踪(nc)) {
                    返回;
                }
                如果 (nc.首位 <= 位置) {
                    如果 (nc.首位 >= 最佳结果.首位) {
                        最佳结果 = nc;
                    }
                    如果 (位置 < nc.尾位) {
                        遍历子节点(nc, 访问);
                        返回 为真;
                    }
                    否则 {
                        调试_.断言(nc.尾位 <= 位置);
                        位置之前的最后一个节点 = nc;
                    }
                }
                否则 {
                    调试_.断言(nc.首位 > 位置);
                    返回 为真;
                }
            }
        }

        函数 检查改变范围(源文件: 源文件_, 新文本: 文字, 文本改变范围: 文本改变范围_, 侵略性检查: 真假) {
            常量 旧文本 = 源文件.文本;
            如果 (文本改变范围) {
                调试_.断言((旧文本.长度 - 文本改变范围.跨度.长度 + 文本改变范围.新长度) === 新文本.长度);

                如果 (侵略性检查 || 调试_.应该断言(断言等级_.最积极_)) {
                    常量 旧文本前缀 = 旧文本.子文本(0, 文本改变范围.跨度.开始);
                    常量 新文本前缀 = 新文本.子文本(0, 文本改变范围.跨度.开始);
                    调试_.断言(旧文本前缀 === 新文本前缀);

                    常量 旧文本后缀 = 旧文本.子文字(文本跨度首位(文本改变范围.跨度), 旧文本.长度);
                    常量 新文本后缀 = 新文本.子文字(文本跨度首位(文本改变范围新跨度(文本改变范围)), 新文本.长度);
                    调试_.断言(旧文本后缀 === 新文本后缀);
                }
            }
        }

        接口 增量元素 扩展 文本范围_ {
            父节点: 节点_;
            相交改变: 真假;
            长度?: 数字;
            _子节点: 节点_[];
        }

        导出 接口 增量节点_ 扩展 节点_, 增量元素 {
            已增量分析: 真假;
        }

        接口 增量节点数组_ 扩展 节点数组_<增量节点_>, 增量元素 {
            长度: 数字;
        }

        导出 接口 语法光标_ {
            当前节点(位置: 数字): 增量节点_;
        }

        函数 创建语法光标(源文件: 源文件_): 语法光标_ {
            变量 当前数组: 节点数组_<节点_> = 源文件.语句组;
            变量 当前数组索引 = 0;
            调试_.断言(当前数组索引 < 当前数组.长度);
            变量 当前 = 当前数组[当前数组索引];
            变量 上次查询位置 = 无效位置_.值_;

            返回 {
                当前节点(位置: 数字) {
                    如果 (位置 !== 上次查询位置) {
                        如果 (当前 && 当前.尾位 === 位置 && 当前数组索引 < (当前数组.长度 - 1)) {
                            当前数组索引++;
                            当前 = 当前数组[当前数组索引];
                        }
                        如果 (!当前 || 当前.首位 !== 位置) {
                            查找启动位置的最高列表元素(位置);
                        }
                    }
                    上次查询位置 = 位置;
                    调试_.断言(!当前 || 当前.首位 === 位置);
                    返回 <增量节点_>当前;
                }
            };
            函数 查找启动位置的最高列表元素(位置: 数字) {
                当前数组 = 未定!;
                当前数组索引 = 无效位置_.值_;
                当前 = 未定!;
                遍历子节点(源文件, 访问节点, 访问数组);
                返回;

                函数 访问节点(n: 节点_) {
                    如果 (位置 >= n.首位 && 位置 < n.尾位) {
                        遍历子节点(n, 访问节点, 访问数组);
                        返回 为真;
                    }
                    返回 为假;
                }

                函数 访问数组(数组: 节点数组_<节点_>) {
                    如果 (位置 >= 数组.首位 && 位置 < 数组.尾位) {
                        循环 (变量 i = 0; i < 数组.长度; i++) {
                            常量 子节点 = 数组[i];
                            如果 (子节点) {
                                如果 (子节点.首位 === 位置) {
                                    当前数组 = 数组;
                                    当前数组索引 = i;
                                    当前 = 子节点;
                                    返回 为真;
                                }
                                否则 {
                                    如果 (子节点.首位 < 位置 && 位置 < 子节点.尾位) {
                                        遍历子节点(子节点, 访问节点, 访问数组);
                                        返回 为真;
                                    }
                                }
                            }
                        }
                    }
                    返回 为假;
                }
            }
        }

        常量 枚举 无效位置_ {
            值_ = -1
        }
    }

    函数 是声明文件名称(文件名: 文字): 真假 {
        返回 文件扩展是(文件名, 扩展名_.DK);
    }
}
